comparison src/g23m-fad/ip/ip_kerp.c @ 174:90eb61ecd093

src/g23m-fad: initial import from TCS3.2/LoCosto
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 12 Oct 2016 05:40:46 +0000
parents
children
comparison
equal deleted inserted replaced
173:bf64d785238a 174:90eb61ecd093
1 /*
2 +----------------------------------------------------------------------------
3 | Project :
4 | Modul :
5 +----------------------------------------------------------------------------
6 | Copyright 2002 Texas Instruments Berlin, AG
7 | All rights reserved.
8 |
9 | This file is confidential and a trade secret of Texas
10 | Instruments Berlin, AG
11 | The receipt of or possession of this file does not convey
12 | any rights to reproduce or disclose its contents or to
13 | manufacture, use, or sell anything it may describe, in
14 | whole, or in part, without the specific written consent of
15 | Texas Instruments Berlin, AG.
16 +----------------------------------------------------------------------------
17 | Purpose : This Modul defines the functions for processing
18 | of incomming primitives for the component
19 | Internet Protocol of the mobile station
20 +----------------------------------------------------------------------------
21 */
22
23 #define ENTITY_IP
24
25 /*==== INCLUDES ===================================================*/
26
27 #include <string.h>
28 #include "typedefs.h"
29 #include "pconst.cdg"
30 #include "vsi.h"
31 #include "macdef.h" /* Get PFREE_DESC2 */
32 #include "pconst.cdg"
33 #include "custom.h"
34 #include "gsm.h"
35 #include "cnf_ip.h"
36 #include "mon_ip.h"
37 #include "prim.h"
38 #include "pei.h"
39 #include "tok.h"
40 #include "ccdapi.h"
41
42 #include "dti.h" /* To get DTI lib */
43 #include "ip.h"
44 #include "ip_udp.h"
45
46 /*==== CONST =======================================================*/
47
48 /*==== TYPES =======================================================*/
49
50 /*==== VAR EXPORT ==================================================*/
51
52 /*==== VAR LOCAL ===================================================*/
53
54 /*==== MACROS ======================================================*/
55
56 /*==== Prototypes ==================================================*/
57
58 /*==== FUNCTIONS ===================================================*/
59
60 /*
61 +--------------------------------------------------------------------+
62 | PROJECT : WAP MODULE : IP_KERP |
63 | STATE : code ROUTINE : ker_ipa_dti_req |
64 +--------------------------------------------------------------------+
65
66 PURPOSE : Process IPA_DTI_REQ primitive
67 */
68 void ker_ipa_dti_req (T_IPA_DTI_REQ * ipa_dti_req)
69 {
70 T_KER * p_ker = & ip_data->ker;
71 BOOL confirm = TRUE;
72 UBYTE dti_conn = IPA_DISCONNECT_DTI;
73
74 PACCESS (ipa_dti_req);
75 TRACE_FUNCTION ("ker_ipa_dti_req()");
76
77 switch (GET_STATE (KER)) {
78 case DEACTIVATED:
79 switch (ipa_dti_req->dti_conn) {
80 case IPA_CONNECT_DTI:
81 switch (ipa_dti_req->dti_direction) {
82 case IPA_DTI_TO_HIGHER_LAYER:
83 if (p_ker->entity_name_hl[0] EQ 0)
84 {
85 hCommHL = vsi_c_open (
86 VSI_CALLER (char *) ipa_dti_req->entity_name
87 );
88 if (hCommHL > VSI_OK)
89 {
90 p_ker->link_id_hl = ipa_dti_req->link_id;
91 strcpy (
92 p_ker->entity_name_hl,
93 (char *) ipa_dti_req->entity_name
94 );
95 SET_STATE (HILA, CONNECTING);
96 if (dti_open (
97 ip_hDTI,
98 IP_DTI_DEF_INSTANCE,
99 IP_DTI_HL_INTERFACE,
100 IP_DTI_DEF_CHANNEL,
101 IP_DTI_UPLINK_QUEUE_SIZE,
102 DTI_CHANNEL_TO_HIGHER_LAYER,
103 FLOW_CNTRL_ENABLED,
104 DTI_VERSION_10,
105 (U8 *) ipa_dti_req->entity_name,
106 ipa_dti_req->link_id
107 ) == TRUE)
108 {
109 confirm = FALSE;
110 }
111 else
112 { /* dti_open failed, close vsi handle */
113 vsi_c_close (VSI_CALLER hCommHL);
114 hCommHL = VSI_ERROR;
115 }
116 }
117 }
118 else
119 {
120 TRACE_ERROR ("DTI link to higher layer already requested");
121 }
122 break;
123 case IPA_DTI_TO_LOWER_LAYER:
124 if (p_ker->entity_name_ll[0] EQ 0)
125 {
126 p_ker->link_id_ll = ipa_dti_req->link_id;
127 strcpy (
128 p_ker->entity_name_ll,
129 (char *) ipa_dti_req->entity_name
130 );
131 SET_STATE (LOLA, CONNECTING);
132 if (dti_open (
133 ip_hDTI,
134 IP_DTI_DEF_INSTANCE,
135 IP_DTI_LL_INTERFACE,
136 IP_DTI_DEF_CHANNEL,
137 IP_DTI_DOWNLINK_QUEUE_SIZE,
138 DTI_CHANNEL_TO_LOWER_LAYER,
139 FLOW_CNTRL_ENABLED,
140 DTI_VERSION_10,
141 (U8 *) ipa_dti_req->entity_name,
142 ipa_dti_req->link_id
143 ) == TRUE)
144 {
145 confirm = FALSE;
146 }
147 }
148 else
149 {
150 TRACE_ERROR ("DTI link to lower layer already requested");
151 }
152 break;
153 default:
154 TRACE_ERROR ("illegal parameter (ipa_dti_req->dti_direction)");
155 } /* End "switch (ipa_dti_req->dti_direction)" */
156 dti_conn = IPA_DISCONNECT_DTI;
157 break;
158 case IPA_DISCONNECT_DTI:
159 if (p_ker->link_id_hl == ipa_dti_req->link_id)
160 {
161 dti_close (
162 ip_hDTI,
163 IP_DTI_DEF_INSTANCE,
164 IP_DTI_HL_INTERFACE,
165 IP_DTI_DEF_CHANNEL,
166 FALSE
167 );
168 p_ker->link_id_hl = IPA_LINK_ID_DEFAULT;
169 p_ker->entity_name_hl[0] = '\0';
170 vsi_c_close (VSI_CALLER hCommHL);
171 hCommHL = VSI_ERROR;
172 SET_STATE (HILA, DOWN);
173 dti_conn = IPA_DISCONNECT_DTI;
174 /*XXX check for remaining UP/DOWN-LINK DTI connections, XXX*/
175 /*XXX terminate_ip() if nothing left open XXX*/
176 }
177 else if (p_ker->link_id_ll == ipa_dti_req->link_id)
178 {
179 dti_close (
180 ip_hDTI,
181 IP_DTI_DEF_INSTANCE,
182 IP_DTI_LL_INTERFACE,
183 IP_DTI_DEF_CHANNEL,
184 FALSE
185 );
186 p_ker->link_id_ll = IPA_LINK_ID_DEFAULT;
187 p_ker->entity_name_ll[0] = '\0';
188 SET_STATE (LOLA, DOWN);
189 dti_conn = IPA_DISCONNECT_DTI;
190 /*XXX check for remaining UP/DOWN-LINK DTI connections, XXX*/
191 /*XXX terminate_ip() if nothing left open XXX*/
192 }
193 else
194 {
195 TRACE_ERROR ("illegal parameter (ipa_dti_req->dti_conn)");
196 dti_conn = IPA_CONNECT_DTI;
197 }
198 break;
199 } /* End "switch (ipa_dti_req->dti_conn)" */
200 break;
201 case ACTIVE_NC:
202 switch (ipa_dti_req->dti_conn) {
203 case IPA_DISCONNECT_DTI:
204 if (p_ker->link_id_hl == ipa_dti_req->link_id)
205 {
206 dti_close (
207 ip_hDTI,
208 IP_DTI_DEF_INSTANCE,
209 IP_DTI_HL_INTERFACE,
210 IP_DTI_DEF_CHANNEL,
211 FALSE
212 );
213 p_ker->link_id_hl = IPA_LINK_ID_DEFAULT;
214 p_ker->entity_name_hl[0] = '\0';
215 vsi_c_close (VSI_CALLER hCommHL);
216 hCommHL = VSI_ERROR;
217 SET_STATE (HILA, DOWN);
218 dti_conn = IPA_DISCONNECT_DTI;
219 SET_STATE (KER, DEACTIVATED);
220 }
221 else if (p_ker->link_id_ll == ipa_dti_req->link_id)
222 {
223 dti_close (
224 ip_hDTI,
225 IP_DTI_DEF_INSTANCE,
226 IP_DTI_LL_INTERFACE,
227 IP_DTI_DEF_CHANNEL,
228 FALSE
229 );
230 p_ker->link_id_ll = IPA_LINK_ID_DEFAULT;
231 p_ker->entity_name_ll[0] = '\0';
232 SET_STATE (LOLA, DOWN);
233 dti_conn = IPA_DISCONNECT_DTI;
234 SET_STATE (KER, DEACTIVATED);
235 }
236 break;
237 default:
238 TRACE_ERROR ("unexpected parameter (ipa_dti_req->dti_conn)");
239 dti_conn = IPA_DISCONNECT_DTI;
240 break;
241 } /* End "switch (ipa_dti_req->dti_conn)" */
242 break;
243 case CONNECTED:
244 default:
245 TRACE_ERROR ("unexpected IPA_DTI_REQ");
246 if (ipa_dti_req->dti_conn == IPA_CONNECT_DTI)
247 dti_conn = IPA_DISCONNECT_DTI;
248 else
249 dti_conn = IPA_CONNECT_DTI;
250 break;
251 } /* End "switch (GET_STATE (KER))" */
252
253 if (confirm)
254 {
255 PALLOC (ipa_dti_cnf, IPA_DTI_CNF);
256 ipa_dti_cnf->dti_conn = dti_conn;
257 ipa_dti_cnf->link_id = ipa_dti_req->link_id;
258 PSENDX (MMI, ipa_dti_cnf);
259 }
260 PFREE (ipa_dti_req);
261 }
262
263 /*
264 +--------------------------------------------------------------------+
265 | PROJECT : WAP MODULE : IP_KERP |
266 | STATE : code ROUTINE : sig_dti_ker_connection_opened_hl_ind |
267 +--------------------------------------------------------------------+
268
269 PURPOSE : Process signal SIG_DTI_KER_CONNECTION_OPENED_HL_IND
270 */
271 void sig_dti_ker_connection_opened_hl_ind ()
272 {
273 T_KER * p_ker = & ip_data->ker;
274
275 TRACE_FUNCTION ("sig_dti_ker_connection_opened_hl_ind()");
276
277 if (GET_STATE (HILA) EQ CONNECTING)
278 {
279 SET_STATE (HILA, IDLE);
280 switch (GET_STATE (LOLA)) {
281 case IDLE:
282 case SEND:
283 case WAIT:
284 SET_STATE (KER, ACTIVE_NC);
285 dti_start (
286 ip_hDTI,
287 IP_DTI_DEF_INSTANCE,
288 IP_DTI_LL_INTERFACE,
289 IP_DTI_DEF_CHANNEL
290 );
291 break;
292 default:
293 break;
294 }
295 {
296 PALLOC (ipa_dti_cnf, IPA_DTI_CNF);
297 ipa_dti_cnf->link_id = p_ker->link_id_hl;
298 ipa_dti_cnf->dti_conn = IPA_CONNECT_DTI;
299 PSENDX (MMI, ipa_dti_cnf);
300 }
301 } else {
302 TRACE_ERROR ("unexpected dti_connect_ind (from higher layer)");
303 }
304 }
305
306 /*
307 +--------------------------------------------------------------------+
308 | PROJECT : WAP MODULE : IP_KERP |
309 | STATE : code ROUTINE : sig_dti_ker_connection_opened_ll_ind |
310 +--------------------------------------------------------------------+
311
312 PURPOSE : Process signal SIG_DTI_KER_CONNECTION_OPENED_LL_IND
313 */
314 void sig_dti_ker_connection_opened_ll_ind ()
315 {
316 T_KER * p_ker = & ip_data->ker;
317
318 TRACE_FUNCTION ("sig_dti_ker_connection_opened_ll_ind()");
319
320 if (GET_STATE (LOLA) EQ CONNECTING)
321 {
322 SET_STATE (LOLA, IDLE);
323 switch (GET_STATE (HILA)) {
324 case IDLE:
325 case SEND:
326 case WAIT:
327 SET_STATE (KER, ACTIVE_NC);
328 dti_start (
329 ip_hDTI,
330 IP_DTI_DEF_INSTANCE,
331 IP_DTI_HL_INTERFACE,
332 IP_DTI_DEF_CHANNEL
333 );
334 break;
335 default:
336 break;
337 }
338 {
339 PALLOC (ipa_dti_cnf, IPA_DTI_CNF);
340 ipa_dti_cnf->link_id = p_ker->link_id_ll;
341 ipa_dti_cnf->dti_conn = IPA_CONNECT_DTI;
342 PSENDX (MMI, ipa_dti_cnf);
343 }
344 } else {
345 TRACE_ERROR ("unexpected dti_connect_ind (from lower layer)");
346 }
347 }
348
349 /*
350 +--------------------------------------------------------------------+
351 | PROJECT : WAP MODULE : IP_KERP |
352 | STATE : code ROUTINE : sig_dti_ker_connection_closed_hl_ind |
353 +--------------------------------------------------------------------+
354
355 PURPOSE : Process signal SIG_DTI_KER_CONNECTION_CLOSED_HL_IND
356 */
357 void sig_dti_ker_connection_closed_hl_ind ()
358 {
359 T_KER * p_ker = & ip_data->ker;
360
361 TRACE_FUNCTION ("sig_dti_ker_connection_closed_hl_ind()");
362
363 SET_STATE (HILA, DOWN);
364
365 switch (GET_STATE (KER)) {
366 case CONNECTED:
367 /*XXX bad case, switch to DEACTIVATED, prune buffers ... XXX*/
368 TRACE_ERROR ("unexpected DTI connection close by peer (UPLINK)");
369 SET_STATE (KER, DEACTIVATED);
370 break;
371 case ACTIVE_NC:
372 SET_STATE (KER, DEACTIVATED);
373 break;
374 default:
375 break;
376 } /* End "switch (GET_STATE (KER))" */
377
378 {
379 PALLOC (ipa_dti_ind, IPA_DTI_IND);
380 ipa_dti_ind->link_id = p_ker->link_id_hl;
381 p_ker->link_id_hl = IPA_LINK_ID_DEFAULT;
382 vsi_c_close (VSI_CALLER hCommHL);
383 hCommHL = VSI_ERROR;
384 p_ker->entity_name_hl[0] = '\0';
385 PSENDX (MMI, ipa_dti_ind);
386 }
387 }
388
389 /*
390 +--------------------------------------------------------------------+
391 | PROJECT : WAP MODULE : IP_KERP |
392 | STATE : code ROUTINE : sig_dti_ker_connection_closed_ll_ind |
393 +--------------------------------------------------------------------+
394
395 PURPOSE : Process signal SIG_DTI_KER_CONNECTION_CLOSED_LL_IND
396 */
397 void sig_dti_ker_connection_closed_ll_ind ()
398 {
399 T_KER * p_ker = & ip_data->ker;
400
401 TRACE_FUNCTION ("sig_dti_ker_connection_closed_ll_ind()");
402
403 /* Caution!!! this return is absolut necessary for WAP over GPRS. Otherwise IP will
404 close itself after SNDCP went down. Unfortunately not everything is deinitialized and
405 IP will never come up on subsequent activation requests (eg. p_ker->entity_name_ll[0]
406 is not wiped). Since the Dti-Manager of ACI closes each DTI-Connection itself, we can
407 suspend this automatism for now */
408 /* return; out-commented at the moment: jk */
409
410 /* If this automatism is re-enabled at least the following lines are necessary
411 and were missing in previous versions!!! But at least we should not store an indication
412 of an connected peer inside the p_ker->entity_name_ll ... */
413
414 /* p_ker->link_id_ll = IPA_LINK_ID_DEFAULT; out-commented at the moment: jk */
415 /* p_ker->entity_name_ll[0] = '\0'; out-commented at the moment: jk */
416 /* SET_STATE (LOLA, DOWN); out-commented at the moment: jk */
417
418 switch (GET_STATE (KER)) {
419 case CONNECTED:
420 /*XXX bad case, switch to DEACTIVATED, prune buffers ... XXX*/
421 TRACE_ERROR ("unexpected DTI connection close by peer (DOWNLINK)");
422 SET_STATE (KER, DEACTIVATED);
423 break;
424 case ACTIVE_NC:
425 SET_STATE (KER, DEACTIVATED);
426 break;
427 default:
428 break;
429 } /* End "switch (GET_STATE (KER))" */
430
431 {
432 PALLOC (ipa_dti_ind, IPA_DTI_IND);
433
434 ipa_dti_ind->link_id = p_ker->link_id_ll; /* Initialize the only one parameter of the prim */
435 p_ker->link_id_ll = IPA_LINK_ID_DEFAULT; /* Set the state of the entity properly */
436 p_ker->entity_name_ll[0] = '\0';
437 SET_STATE (LOLA, DOWN);
438 SET_STATE (KER, DEACTIVATED);
439
440 PSENDX (MMI, ipa_dti_ind); /* Send indication to the MMI */
441 }
442 }
443
444 /*
445 +--------------------------------------------------------------------+
446 | PROJECT : WAP MODULE : IP_KERP |
447 | STATE : code ROUTINE : sig_dti_ker_tx_buffer_full_ll_ind |
448 +--------------------------------------------------------------------+
449
450 PURPOSE : Process signal SIG_DTI_KER_TX_BUFFER_FULL_LL_IND
451 */
452 void sig_dti_ker_tx_buffer_full_ll_ind ()
453 {
454 TRACE_FUNCTION ("sig_dti_ker_tx_buffer_full_ll_ind()");
455 }
456
457 /*
458 +--------------------------------------------------------------------+
459 | PROJECT : WAP MODULE : IP_KERP
460 | STATE : code ROUTINE : sig_dti_ker_tx_buffer_full_hl_ind |
461 +--------------------------------------------------------------------+
462
463 PURPOSE : Process signal SIG_DTI_KER_TX_BUFFER_FULL_HL_IND
464 */
465 void sig_dti_ker_tx_buffer_full_hl_ind ()
466 {
467 TRACE_FUNCTION ("sig_dti_ker_tx_buffer_full_hl_ind()");
468 }
469
470 /*
471 +--------------------------------------------------------------------+
472 | PROJECT : WAP MODULE : IP_KERP |
473 | STATE : code ROUTINE : ker_ipa_config_req |
474 +--------------------------------------------------------------------+
475
476 PURPOSE : Process primitive IPA_CONFIG_REQ received from ACI
477 */
478 void ker_ipa_config_req (T_IPA_CONFIG_REQ * ipa_config_req)
479 {
480 T_KER * p_ker = & ip_data->ker;
481 PALLOC (ipa_config_cnf, IPA_CONFIG_CNF);
482
483 TRACE_FUNCTION ("ker_ipa_config_req()");
484
485 PACCESS (ipa_config_req);
486
487 switch (GET_STATE (KER)) {
488 case DEACTIVATED:
489 ipa_config_cnf->ack_flag = IPA_CONFIG_NAK;
490 ipa_config_cnf->all_down = IPA_ALLDOWN_TRUE;
491 break;
492 case ACTIVE_NC:
493 switch (ipa_config_req->cmd) {
494 case IPA_CONFIG_UP:
495 p_ker->source_addr= ipa_config_req->ip;
496 p_ker->peer_addr = ipa_config_req->peer_ip;
497 p_ker->mtu = ipa_config_req->mtu;
498 SET_STATE (KER, CONNECTED);
499 dti_start (
500 ip_hDTI,
501 IP_DTI_DEF_INSTANCE,
502 IP_DTI_LL_INTERFACE,
503 IP_DTI_DEF_CHANNEL
504 );
505 ipa_config_cnf->ack_flag = IPA_CONFIG_ACK;
506 ipa_config_cnf->all_down = IPA_ALLDOWN_FALSE;
507 break;
508 case IPA_CONFIG_DOWN:
509 ipa_config_cnf->ack_flag = IPA_CONFIG_NAK;
510 ipa_config_cnf->all_down = IPA_ALLDOWN_TRUE;
511 break;
512 }
513 break;
514 case CONNECTED:
515 switch (ipa_config_req->cmd) {
516 case IPA_CONFIG_UP:
517 ipa_config_cnf->ack_flag = IPA_CONFIG_NAK;
518 ipa_config_cnf->all_down = IPA_ALLDOWN_FALSE;
519 break;
520 case IPA_CONFIG_DOWN:
521 /*XXX prune buffers + config data XXX*/
522 SET_STATE (KER, ACTIVE_NC);
523 ipa_config_cnf->ack_flag = IPA_CONFIG_ACK;
524 ipa_config_cnf->all_down = IPA_ALLDOWN_TRUE;
525 config_down_ll ();
526 break;
527 }
528 break;
529 } /* End "switch (GET_STATE (KER))" */
530
531 PSENDX (MMI, ipa_config_cnf);
532 PFREE (ipa_config_req);
533 }
534
535 /*
536 +--------------------------------------------------------------------+
537 | PROJECT : WAP MODULE : IP_KERP |
538 | STATE : code ROUTINE : ker_ip_addr_req |
539 +--------------------------------------------------------------------+
540
541 PURPOSE : Process primitive IP_ADDR_REQ received from higher layer
542 */
543 void ker_ip_addr_req (T_IP_ADDR_REQ * ip_addr_req)
544 {
545 T_KER * p_ker = & ip_data->ker;
546
547 TRACE_FUNCTION ("ker_ip_addr_req()");
548
549 PACCESS (ip_addr_req);
550
551 switch (GET_STATE (KER)) {
552 case DEACTIVATED:
553 if (GET_STATE (HILA) NEQ DOWN)
554 {
555 PALLOC (ip_addr_cnf, IP_ADDR_CNF);
556 ip_addr_cnf->src_addr = p_ker->source_addr;
557 ip_addr_cnf->err = IP_ADDR_NOROUTE;
558 ip_addr_cnf->trans_prot = ip_addr_req->trans_prot;
559 PSENDX (HL, ip_addr_cnf);
560 }
561 else
562 {
563 TRACE_ERROR ("IP_ADDR_REQ received but no higher layer known");
564 }
565 break;
566 case ACTIVE_NC:
567 {
568 PALLOC (ip_addr_cnf, IP_ADDR_CNF);
569 ip_addr_cnf->src_addr = p_ker->source_addr;
570 ip_addr_cnf->err = IP_ADDR_NOROUTE;
571 ip_addr_cnf->trans_prot = ip_addr_req->trans_prot;
572 PSENDX (HL, ip_addr_cnf);
573 }
574 break;
575 case CONNECTED:
576 {
577 PALLOC (ip_addr_cnf, IP_ADDR_CNF);
578 ip_addr_cnf->src_addr = p_ker->source_addr;
579 ip_addr_cnf->err = IP_ADDR_NOERROR;
580 ip_addr_cnf->trans_prot = ip_addr_req->trans_prot;
581 PSENDX (HL, ip_addr_cnf);
582 }
583 break;
584 } /* End "switch (GET_STATE (KER))" */
585
586 PFREE (ip_addr_req);
587 }
588
589 /*
590 +--------------------------------------------------------------------+
591 | PROJECT : WAP MODULE : ip_kerp.c |
592 | STATE : code ROUTINE : sig_dti_ker_data_received_hl_ind |
593 +--------------------------------------------------------------------+
594
595 UDP
596 |
597 V
598 IP
599
600 PURPOSE : Process signal SIG_DTI_KER_DATA_RECEIVED_HL_IND
601 */
602 void sig_dti_ker_data_received_hl_ind (T_DTI2_DATA_REQ * dti_data_req)
603 {
604 T_HILA * p_hl = & ip_data->hila;
605 T_KER * p_ker = & ip_data->ker;
606 BOOL dest_addresses[MAX_ADDR_TYPES];
607 BOOL src_addresses[MAX_ADDR_TYPES];
608 BOOL send_ready = FALSE;
609
610 TRACE_FUNCTION ("sig_dti_ker_data_received_hl_ind()");
611
612 if (dti_data_req == NULL)
613 return;
614
615 PACCESS (dti_data_req);
616
617 switch (GET_STATE (KER)) {
618 case DEACTIVATED:
619 case ACTIVE_NC: /* Fall through */
620 PFREE_DESC2 (dti_data_req);
621 break;
622 case CONNECTED:
623 if (ip_packet_validator (& dti_data_req->desc_list2))
624 {
625 T_desc_list2 * desc_list;
626 T_desc2 * desc;
627 UBYTE * ip_header, to_do;
628 USHORT packet_len;
629
630 p_hl->dti_data_req = dti_data_req;
631 desc_list = & p_hl->dti_data_req->desc_list2;
632 desc = (T_desc2 *) desc_list->first;
633 ip_header = desc->buffer;
634 to_do = B_NORMAL_PACKET;
635
636 dti_stop (
637 ip_hDTI,
638 IP_DTI_DEF_INSTANCE,
639 IP_DTI_HL_INTERFACE,
640 IP_DTI_DEF_CHANNEL
641 );
642
643 /* Check destination and source address */
644 {
645 ULONG dest_addr = GET_IP_DEST_ADDR (ip_header);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
646 check_ip_address (
647 dest_addresses,
648 src_addresses,
649 dest_addr,
650 p_ker->source_addr
651 );
652 if (src_addresses[BAD_UL_SRC_ADDR] OR dest_addresses[BAD_UL_DEST_ADDR])
653 p_hl->drop_packet = TRUE;
654 }
655
656 /* Check if ICMP message from higher layer and build the ICMP packet */
657 if ((GET_IP_PROT (ip_header) EQ ICMP_PROT) AND (! p_hl->drop_packet))/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
658 build_ip_packet (TRUE, B_ICMP_PACKET);
659
660 /* Check if fragmenting necessary - build the fragment */
661 packet_len = p_hl->dti_data_req->desc_list2.list_len;
662
663 if ((packet_len > p_ker->mtu) AND (! p_hl->drop_packet))
664 {
665 to_do = B_SEGMENT;
666 build_ip_packet (TRUE, to_do);
667 }
668
669 /* Build "normal" IP packet */
670 if ((to_do EQ B_NORMAL_PACKET) AND (! p_hl->drop_packet))
671 build_ip_packet (TRUE, to_do);
672
673 /* Check if ICMP message is to be send */
674 if ((p_ker->send_icmp) AND (GET_STATE (HILA) EQ WAIT))
675 {
676 T_DTI2_DATA_REQ * data_req = p_ker->icmp_dti_data_req;
677 data_req->parameters.p_id = DTI_PID_IP;
678 data_req->parameters.st_lines.st_flow = DTI_FLOW_ON;
679 data_req->parameters.st_lines.st_line_sa = DTI_SA_ON;
680 data_req->parameters.st_lines.st_line_sb = DTI_SB_ON;
681 data_req->parameters.st_lines.st_break_len = DTI_BREAK_OFF;
682
683 {
684 PPASS (data_req, dti_data_ind, DTI2_DATA_IND);
685 dti_send_data (
686 ip_hDTI,
687 IP_DTI_DEF_INSTANCE,
688 IP_DTI_HL_INTERFACE,
689 IP_DTI_DEF_CHANNEL,
690 dti_data_ind
691 );
692 }
693 SET_STATE (HILA, IDLE);
694 dti_start (
695 ip_hDTI,
696 IP_DTI_DEF_INSTANCE,
697 IP_DTI_HL_INTERFACE,
698 IP_DTI_DEF_CHANNEL
699 );
700 }
701
702 /* Bad packet - drop */
703 if (p_hl->drop_packet)
704 {
705 p_hl->drop_packet = FALSE;
706 PFREE_DESC2 (p_hl->dti_data_req);
707 send_ready = TRUE;
708 }
709 else
710 {
711 if (GET_STATE (HILA) EQ WAIT)
712 {
713 /* Send dti2_data_req */
714 dti_data_req->parameters.p_id = DTI_PID_IP;
715 dti_data_req->parameters.st_lines.st_flow = DTI_FLOW_ON;
716 dti_data_req->parameters.st_lines.st_line_sa = DTI_SA_ON;
717 dti_data_req->parameters.st_lines.st_line_sb = DTI_SB_ON;
718 dti_data_req->parameters.st_lines.st_break_len = DTI_BREAK_OFF;
719
720 PACCESS (dti_data_req);
721 {
722 PPASS (dti_data_req, dti_data_ind, DTI2_DATA_IND);
723 dti_send_data (
724 ip_hDTI,
725 IP_DTI_DEF_INSTANCE,
726 IP_DTI_LL_INTERFACE,
727 IP_DTI_DEF_CHANNEL,
728 dti_data_ind
729 );
730 }
731 p_hl->dti_data_req = NULL;
732 if (p_hl->state_segment EQ NO_SEGMENTS)
733 {
734 SET_STATE (HILA, IDLE);
735 send_ready = TRUE;
736 }
737 else
738 {
739 /* When the ready_ind is received, we don't know whether
740 * the first segment has been sent or not (state is sent
741 * in any case), so we don't know whether we have to transmit
742 * the first or to build the next one. To avoid the problem
743 * we build the next packet here. */
744 build_ip_packet (TRUE, B_SEGMENT);
745 SET_STATE (HILA, SEND);
746 send_ready = FALSE;
747 }
748 }
749 else
750 {
751 SET_STATE (HILA, SEND);
752 }
753 }
754 /* Send ready indication to higher layer */
755 if (send_ready)
756 {
757 dti_start (
758 ip_hDTI,
759 IP_DTI_DEF_INSTANCE,
760 IP_DTI_HL_INTERFACE,
761 IP_DTI_DEF_CHANNEL
762 );
763 }
764 }
765 else
766 {
767 PFREE_DESC2 (dti_data_req);
768 }
769 break;
770 } /* End "switch (GET_STATE (KER))" */
771 }
772
773 /*
774 +--------------------------------------------------------------------+
775 | PROJECT : WAP MODULE : ip_kerp.c |
776 | STATE : code ROUTINE : sig_dti_ker_data_received_ll_ind |
777 +--------------------------------------------------------------------+
778
779 IP
780 ^
781 |
782 PPP
783
784 PURPOSE : Process signal SIG_DTI_KER_DATA_RECEIVED_LL_IND
785 */
786 void sig_dti_ker_data_received_ll_ind (T_DTI2_DATA_IND * dti_data_ind)
787 {
788 T_LOLA * p_ll = & ip_data->lola;
789 T_KER * p_ker = & ip_data->ker;
790
791 TRACE_FUNCTION ("sig_dti_ker_data_received_ll_ind()");
792
793 if (dti_data_ind == NULL)
794 return;
795
796 PACCESS (dti_data_ind);
797
798 switch (GET_STATE (KER)) {
799 case DEACTIVATED:
800 case ACTIVE_NC: /* Fall through */
801 PFREE_DESC2 (dti_data_ind);
802 break;
803 case CONNECTED:
804 if (ip_packet_validator (& dti_data_ind->desc_list2))
805 {
806 BOOL send_getdata_req;
807 T_desc_list2 * desc_list;
808 T_desc2 * desc;
809 UBYTE * ip_header, to_do, ip_prot;
810 USHORT header_len_b;
811 USHORT header_chksum, chksum;
812 ULONG source_addr, dest_addr;
813 BOOL dest_addresses[MAX_ADDR_TYPES];
814 BOOL src_addresses[MAX_ADDR_TYPES];
815
816 send_getdata_req = FALSE;
817 p_ll->dti_data_ind = dti_data_ind;
818 desc_list = & p_ll->dti_data_ind->desc_list2;
819 desc = (T_desc2 *) desc_list->first;
820 ip_header = desc->buffer;
821 to_do = BUILD_NO_PACKET;
822 header_len_b = (USHORT) GET_IP_HEADER_LEN_B (ip_header);
823 source_addr = p_ker->source_addr;
824 ip_prot = GET_IP_PROT (ip_header);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
825
826 /* Check IP protocol */
827 if (GET_IP_VERSION (ip_header) NEQ IP_VERSION)
828 p_ll->drop_packet = TRUE;
829 else
830 {
831 UBYTE chk_len_ind;
832 USHORT desc_len;
833
834 /* Check the datagram length */
835 chk_len_ind = chk_packet_len (ip_header, desc_list);
836
837 if (chk_len_ind NEQ NO_ERROR)
838 {
839 /* Datagram > length indicated in header - truncate */
840 if (chk_len_ind EQ CHANGE_PACKET_LEN)
841 {
842 desc_len = (USHORT) GET_IP_TOTAL_LEN (ip_header);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
843 truncate_descs (desc_list, desc_len);
844 }
845 else
846 p_ll->drop_packet = TRUE;
847 }
848 }
849
850 /* Checksum */
851 if (! p_ll->drop_packet)
852 {
853 desc = (T_desc2 *) desc_list->first;
854 header_chksum = (USHORT) GET_IP_CHECKSUM (ip_header);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
855 RESET_IP_CHECKSUM (ip_header);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
856 chksum = inet_checksum (ip_header, header_len_b);
857 SET_IP_CHECKSUM (ip_header, chksum);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
858 if (header_chksum NEQ chksum)
859 {
860 p_ll->drop_packet = TRUE;
861 TRACE_EVENT ("header checksum error indicated") ;
862 }
863 }
864
865 /* Check destination address and source address */
866 if (! p_ll->drop_packet)
867 {
868 dest_addr = GET_IP_DEST_ADDR (ip_header);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
869 check_ip_address (
870 dest_addresses,
871 src_addresses,
872 dest_addr,
873 source_addr
874 );
875 if (src_addresses[BAD_DL_SRC_ADDR] OR dest_addresses[BAD_DL_DEST_ADDR])
876 p_ll->drop_packet = TRUE;
877
878 if (dest_addresses[NO_DEST_ADDR])
879 {
880 /* Send ICMP message if the IP address is ok and
881 * we have not got more than one segment. */
882 if (
883 (ip_prot EQ ICMP_PROT) OR
884 (p_ll->state_reassembly[p_ll->pos_server] EQ READ_SEGMENT) OR
885 dest_addresses[LINK_LAYER_BCAST] OR
886 dest_addresses[BCAST_ADDR_255] OR
887 src_addresses[BCAST_ADDR_255] OR
888 src_addresses[MCAST_ADDR] OR
889 src_addresses[NETW_ADDR] OR
890 src_addresses[LOOP_BACK_ADDR] OR
891 src_addresses[CLASS_E_ADDR]
892 )
893 p_ll->drop_packet = TRUE;
894 else
895 {
896 to_do = B_ICMP_NO_FORWARD;
897 p_ker->send_icmp = TRUE;
898 }
899 }
900 }
901
902 /* Check fragmenting */
903 if ((! p_ll->drop_packet) AND (to_do NEQ B_ICMP_NO_FORWARD))
904 {
905 BOOL df_flag, mf_flag;
906 USHORT fragm_offset;
907 BOOL first_segment, middle_segment, last_segment;
908
909 df_flag = GET_IP_DF_FLAG (ip_header);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
910 mf_flag = GET_IP_MF_FLAG (ip_header);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
911
912 fragm_offset = (USHORT) GET_IP_FRAG_OFFSET (ip_header);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
913 first_segment =
914 (df_flag EQ FLAG_NOT_SET) AND
915 (mf_flag EQ FLAG_SET) AND
916 (fragm_offset EQ 0);
917 middle_segment =
918 (df_flag EQ FLAG_NOT_SET) AND
919 (mf_flag EQ FLAG_SET) AND
920 (fragm_offset > 0);
921 last_segment =
922 (df_flag EQ FLAG_NOT_SET) AND
923 (mf_flag EQ FLAG_NOT_SET) AND
924 (fragm_offset > 0);
925
926 if (first_segment OR middle_segment OR last_segment)
927
928 /* Filter out ICMP fragments - not supported */
929 if (ip_prot EQ ICMP_PROT)
930 p_ll->drop_packet = TRUE;
931 else
932 /* Start reassemble fragments */
933 reassemble_fragments (
934 & p_ll->dti_data_ind,
935 p_ll,
936 ip_header,
937 first_segment,
938 /* middle_segment, */
939 last_segment /*,*/
940 /* fragm_offset */
941 );
942 }
943
944 /* Incoming ICMP message */
945 if (! p_ll->drop_packet)
946 if (ip_prot EQ ICMP_PROT)
947 if (GET_ICMP_TYPE (ip_header, header_len_b) EQ ICMP_TYP_ECHO)
948 {
949 to_do = B_ICMP_ECHO_REPLY;
950 p_ker->send_icmp = TRUE;
951 }
952
953 /* Build selected packets */
954 if ((! p_ll->drop_packet) AND (to_do NEQ BUILD_NO_PACKET))
955 build_ip_packet (FALSE, to_do);
956
957 /* Skip by reading fragments - only send dti_getdata_req */
958 if (p_ll->state_reassembly[p_ll->pos_server] EQ READ_SEGMENT)
959 send_getdata_req = TRUE;
960
961 /* Drop packet and free resources */
962 else if (p_ll->drop_packet)
963 {
964 p_ll->drop_packet = FALSE;
965 PFREE_DESC2 (p_ll->dti_data_ind);
966 p_ll->dti_data_ind = NULL;
967 send_getdata_req = TRUE;
968 }
969 else
970 {
971 /* Send an ICMP message first */
972 if (p_ker->send_icmp EQ TRUE)
973 {
974 if (GET_STATE (HILA) EQ WAIT)
975 {
976 T_DTI2_DATA_REQ * data_req;
977 p_ker->send_icmp = FALSE;
978
979 data_req = p_ker->icmp_dti_data_req;
980 data_req->parameters.p_id = DTI_PID_IP;
981 data_req->parameters.st_lines.st_flow = DTI_FLOW_ON;
982 data_req->parameters.st_lines.st_line_sa = DTI_SA_ON;
983 data_req->parameters.st_lines.st_line_sb = DTI_SB_ON;
984 data_req->parameters.st_lines.st_break_len = DTI_BREAK_OFF;
985
986 PACCESS (data_req);
987 {
988 PPASS (data_req, dti_data_indication, DTI2_DATA_IND);
989 dti_send_data (
990 ip_hDTI,
991 IP_DTI_DEF_INSTANCE,
992 IP_DTI_LL_INTERFACE,
993 IP_DTI_DEF_CHANNEL,
994 dti_data_indication
995 );
996 SET_STATE (HILA, IDLE);
997 p_ker->send_icmp = FALSE;
998 p_ker->icmp_dti_data_req = NULL;
999 send_getdata_req = TRUE; /*XXX not clear to me XXX*/
1000 }
1001 }
1002 }
1003 else
1004 {
1005 /* Check we are not in the middle of a reassembly process */
1006 if (p_ll->state_reassembly[p_ll->pos_server] EQ NO_SEGMENTS)
1007 {
1008 if (GET_STATE (LOLA) EQ WAIT)
1009 {
1010 T_DTI2_DATA_IND * data_ind;
1011
1012 SET_STATE (LOLA, IDLE);
1013
1014 data_ind = p_ll->dti_data_ind;
1015 data_ind->parameters.p_id = DTI_PID_IP;
1016 data_ind->parameters.st_lines.st_flow = DTI_FLOW_ON;
1017 data_ind->parameters.st_lines.st_line_sa = DTI_SA_ON;
1018 data_ind->parameters.st_lines.st_line_sb = DTI_SB_ON;
1019 data_ind->parameters.st_lines.st_break_len = DTI_BREAK_OFF;
1020 dti_send_data (
1021 ip_hDTI,
1022 IP_DTI_DEF_INSTANCE,
1023 IP_DTI_HL_INTERFACE,
1024 IP_DTI_DEF_CHANNEL,
1025 data_ind
1026 );
1027 p_ll->dti_data_ind = NULL;
1028
1029 send_getdata_req = TRUE;
1030 }
1031 else
1032 {
1033 SET_STATE (LOLA, SEND);
1034 }
1035 }
1036 }
1037 }
1038
1039 if (send_getdata_req)
1040 {
1041 dti_start (
1042 ip_hDTI,
1043 IP_DTI_DEF_INSTANCE,
1044 IP_DTI_LL_INTERFACE,
1045 IP_DTI_DEF_CHANNEL
1046 );
1047 }
1048 }
1049 else
1050 {
1051 PFREE_DESC2 (dti_data_ind);
1052 }
1053 break;
1054 } /* End "switch (GET_STATE (KER))" */
1055 }
1056
1057 /*
1058 +--------------------------------------------------------------------+
1059 | PROJECT : WAP MODULE : ip_kerp.c |
1060 | STATE : code ROUTINE : sig_dti_ker_tx_buffer_ready_ll_ind |
1061 +--------------------------------------------------------------------+
1062
1063 "DTI2_READY_IND received"
1064 PURPOSE : Process signal SIG_DTI_KER_TX_BUFFER_READY_LL_IND
1065 */
1066 void sig_dti_ker_tx_buffer_ready_ll_ind ()
1067 {
1068 T_HILA * p_hl = & ip_data->hila;
1069 T_KER * p_ker = & ip_data->ker;
1070 BOOL send_ready = FALSE;
1071
1072 TRACE_FUNCTION ("sig_dti_ker_tx_buffer_ready_ll_ind()");
1073
1074 switch (GET_STATE (KER)) {
1075 case DEACTIVATED:
1076 case ACTIVE_NC: /* Fall through */
1077 SET_STATE (HILA, WAIT);
1078 break;
1079 case CONNECTED:
1080 {
1081 /* Check if ICMP message */
1082 if (p_ker->send_icmp)
1083 {
1084 T_DTI2_DATA_REQ * dti_data_req;
1085 p_ker->send_icmp = FALSE;
1086 dti_data_req = p_ker->icmp_dti_data_req;
1087 dti_data_req->parameters.p_id = DTI_PID_IP;
1088 dti_data_req->parameters.st_lines.st_flow = DTI_FLOW_ON;
1089 dti_data_req->parameters.st_lines.st_line_sa = DTI_SA_ON;
1090 dti_data_req->parameters.st_lines.st_line_sb = DTI_SB_ON;
1091 dti_data_req->parameters.st_lines.st_break_len = DTI_BREAK_OFF;
1092
1093 PACCESS (dti_data_req);
1094 {
1095 PPASS (dti_data_req, dti_data_ind, DTI2_DATA_IND);
1096 dti_send_data (
1097 ip_hDTI,
1098 IP_DTI_DEF_INSTANCE,
1099 IP_DTI_LL_INTERFACE,
1100 IP_DTI_DEF_CHANNEL,
1101 dti_data_ind
1102 );
1103 }
1104 dti_start (
1105 ip_hDTI,
1106 IP_DTI_DEF_INSTANCE,
1107 IP_DTI_HL_INTERFACE,
1108 IP_DTI_DEF_CHANNEL
1109 );
1110 p_ker->send_icmp = FALSE;
1111 p_ker->icmp_dti_data_req = NULL;
1112 }
1113 else if (GET_STATE (HILA) EQ SEND)
1114 {
1115 /* Send waiting data packet */
1116 p_hl->dti_data_req->parameters.p_id = DTI_PID_IP;
1117 p_hl->dti_data_req->parameters.st_lines.st_flow = DTI_FLOW_ON;
1118 p_hl->dti_data_req->parameters.st_lines.st_line_sa = DTI_SA_ON;
1119 p_hl->dti_data_req->parameters.st_lines.st_line_sb = DTI_SB_ON;
1120 p_hl->dti_data_req->parameters.st_lines.st_break_len = DTI_BREAK_OFF;
1121
1122 PACCESS (p_hl->dti_data_req);
1123 {
1124 PPASS (p_hl->dti_data_req, dti_data_ind, DTI2_DATA_IND);
1125 dti_send_data (
1126 ip_hDTI,
1127 IP_DTI_DEF_INSTANCE,
1128 IP_DTI_LL_INTERFACE,
1129 IP_DTI_DEF_CHANNEL,
1130 dti_data_ind
1131 );
1132 }
1133 p_hl->dti_data_req = NULL;
1134 dti_start (
1135 ip_hDTI,
1136 IP_DTI_DEF_INSTANCE,
1137 IP_DTI_LL_INTERFACE,
1138 IP_DTI_DEF_CHANNEL
1139 );
1140 p_hl->dti_data_req = NULL;
1141
1142 /* Check if fragmenting - stay in the same state */
1143 if (p_hl->state_segment EQ NO_SEGMENTS)
1144 {
1145 SET_STATE (HILA, IDLE);
1146 send_ready = TRUE;
1147 }
1148 else
1149 {
1150 /* Fragmentation -> build next packet */
1151 build_ip_packet (TRUE, B_SEGMENT);
1152 if (p_hl->drop_packet)
1153 {
1154 p_hl->drop_packet = FALSE;
1155 PFREE_DESC2 (p_hl->dti_data_req);
1156 SET_STATE (HILA, IDLE);
1157 send_ready = TRUE;
1158 }
1159 }
1160 if (send_ready)
1161 dti_start (
1162 ip_hDTI,
1163 IP_DTI_DEF_INSTANCE,
1164 IP_DTI_HL_INTERFACE,
1165 IP_DTI_DEF_CHANNEL
1166 );
1167 }
1168 else
1169 {
1170 SET_STATE (HILA, WAIT);
1171 }
1172 }
1173 break;
1174 } /* End "switch (GET_STATE (KER))" */
1175 }
1176
1177 /*
1178 +--------------------------------------------------------------------+
1179 | PROJECT : WAP MODULE : ip_kerp.c |
1180 | STATE : code ROUTINE : sig_dti_ker_tx_buffer_ready_hl_ind |
1181 +--------------------------------------------------------------------+
1182
1183 "DTI2_GETDATA_REQ received"
1184 PURPOSE : Process signal SIG_DTI_KER_TX_BUFFER_READY_HL_IND
1185 */
1186 void sig_dti_ker_tx_buffer_ready_hl_ind ()
1187 {
1188 T_LOLA * p_ll = & ip_data->lola;
1189
1190 TRACE_FUNCTION ("sig_dti_ker_tx_buffer_ready_hl_ind()");
1191
1192 switch (GET_STATE (KER)) {
1193 case DEACTIVATED:
1194 case ACTIVE_NC: /* Fall through */
1195 /*XXX ???? XXX*/
1196 break;
1197 case CONNECTED:
1198 {
1199 /* state_send - primitive can be sended */
1200 if (GET_STATE (LOLA) EQ SEND)
1201 {
1202 SET_STATE (LOLA, IDLE);
1203 p_ll->dti_data_ind->parameters.p_id = DTI_PID_IP;
1204 p_ll->dti_data_ind->parameters.st_lines.st_flow = DTI_FLOW_ON;
1205 p_ll->dti_data_ind->parameters.st_lines.st_line_sa = DTI_SA_ON;
1206 p_ll->dti_data_ind->parameters.st_lines.st_line_sb = DTI_SB_ON;
1207 p_ll->dti_data_ind->parameters.st_lines.st_break_len = DTI_BREAK_OFF;
1208
1209 dti_send_data (
1210 ip_hDTI,
1211 IP_DTI_DEF_INSTANCE,
1212 IP_DTI_HL_INTERFACE,
1213 IP_DTI_DEF_CHANNEL,
1214 p_ll->dti_data_ind
1215 );
1216 p_ll->dti_data_ind = NULL;
1217
1218 /* Send DTI2_GETDATA_REQ and indicate ready for new packet */
1219 dti_start (
1220 ip_hDTI,
1221 IP_DTI_DEF_INSTANCE,
1222 IP_DTI_LL_INTERFACE,
1223 IP_DTI_DEF_CHANNEL
1224 );
1225 SET_STATE (LOLA, IDLE);
1226 }
1227 else
1228 {
1229 SET_STATE (LOLA, WAIT);
1230 }
1231 }
1232 break;
1233 } /* End "switch (GET_STATE (KER))" */
1234 }
1235
1236 /*-------------------------------------------------------------------------*/
1237