FreeCalypso > hg > fc-magnetite
view src/g23m-fad/udp/udp_kerp.c @ 640:16eb1b9640dc
target gtm900 renamed to gtm900mgc2
This change reflects the fact that the build target in question supports
MGC2GSMT hardware only, and will NOT work on other hw that confusing bears
the same end user name of GTM900, neither the LoCosto-based GTM900-C
nor the Calypso-based MG01GSMT that has a different and incompatible RFFE.
If we ever get our hands on a piece of MG01GSMT hw and add support for it,
that other target will be named gtm900mg01.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 31 Jan 2020 00:46:07 +0000 |
parents | 90eb61ecd093 |
children |
line wrap: on
line source
/* +---------------------------------------------------------------------------- | Project : | Modul : +---------------------------------------------------------------------------- | Copyright 2002 Texas Instruments Berlin, AG | All rights reserved. | | This file is confidential and a trade secret of Texas | Instruments Berlin, AG | The receipt of or possession of this file does not convey | any rights to reproduce or disclose its contents or to | manufacture, use, or sell anything it may describe, in | whole, or in part, without the specific written consent of | Texas Instruments Berlin, AG. +---------------------------------------------------------------------------- | Purpose : This Modul defines the functions for processing | of incomming primitives for the component | Internet Protocol of the mobile station +---------------------------------------------------------------------------- */ #define ENTITY_UDP /*==== INCLUDES ===================================================*/ #include <string.h> #include "typedefs.h" #include "pcm.h" #include "pconst.cdg" #include "mconst.cdg" #include "message.h" #include "ccdapi.h" #include "vsi.h" #include "macdef.h" /* To get PFREE_DESC2 */ #include "custom.h" #include "gsm.h" #include "prim.h" #include "cnf_udp.h" #include "mon_udp.h" #include "pei.h" #include "tok.h" #include "dti.h" /* To get DTI lib */ #include "udp.h" /*==== CONST =======================================================*/ /*==== TYPES =======================================================*/ /*==== VAR EXPORT ==================================================*/ /*==== VAR LOCAL ===================================================*/ /*==== MACROS ======================================================*/ /*==== Prototypes ==================================================*/ /*==== FUNCTIONS ===================================================*/ /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : UDP_KERP | | STATE : code ROUTINE : ker_udpa_dti_req | +--------------------------------------------------------------------+ PURPOSE : Process UDPA_DTI_REQ primitive */ void ker_udpa_dti_req (T_UDPA_DTI_REQ * udpa_dti_req) { BOOL confirm = TRUE; UBYTE dti_conn = UDPA_DISCONNECT_DTI; PACCESS (udpa_dti_req); TRACE_FUNCTION ("ker_udpa_dti_req()"); switch (GET_STATE (KER)) { case DEACTIVATED: { switch (udpa_dti_req->dti_conn) { case UDPA_CONNECT_DTI: { switch (udpa_dti_req->dti_direction) { case UDPA_DTI_TO_HIGHER_LAYER: if (! * udp_data->hila.entity_name) { hCommHL = vsi_c_open ( VSI_CALLER (char *) udpa_dti_req->entity_name ); if (hCommHL > VSI_OK) { udp_data->hila.link_id = udpa_dti_req->link_id; strcpy ( udp_data->hila.entity_name, (char *) udpa_dti_req->entity_name ); SET_STATE (HILA, CONNECTING); if (dti_open ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_HL_INTERFACE, UDP_DTI_DEF_CHANNEL, UDP_DTI_INIT_QUEUE_SIZE, DTI_CHANNEL_TO_HIGHER_LAYER, FLOW_CNTRL_ENABLED, DTI_VERSION_10, (U8 *) udpa_dti_req->entity_name, udpa_dti_req->link_id ) EQ TRUE) { confirm = FALSE; } else /* dti_open failed, close VSI handle: */ { vsi_c_close (VSI_CALLER hCommHL); hCommHL = VSI_ERROR; } } } else { TRACE_ERROR ("DTI link to higher layer already requested"); } break; case UDPA_DTI_TO_LOWER_LAYER: if (! * udp_data->lola.entity_name) { udp_data->lola.link_id = udpa_dti_req->link_id; strcpy ( udp_data->lola.entity_name, (char *) udpa_dti_req->entity_name ); SET_STATE (LOLA, CONNECTING); if (dti_open ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_LL_INTERFACE, UDP_DTI_DEF_CHANNEL, UDP_DTI_INIT_QUEUE_SIZE, DTI_CHANNEL_TO_LOWER_LAYER, FLOW_CNTRL_ENABLED, DTI_VERSION_10, (U8 *) udpa_dti_req->entity_name, udpa_dti_req->link_id ) EQ TRUE) { confirm = FALSE; } } else { TRACE_ERROR ("DTI link to lower layer already requested"); } break; default: TRACE_ERROR("illegal parameter (udpa_dti_req->dti_direction)"); } /* End switch (udpa_dti_req->dti_direction) */ dti_conn = UDPA_DISCONNECT_DTI; break; } case UDPA_DISCONNECT_DTI: { if (udp_data->hila.link_id EQ udpa_dti_req->link_id) { dti_close ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_HL_INTERFACE, UDP_DTI_DEF_CHANNEL, FALSE ); *udp_data->hila.entity_name = 0; SET_STATE (HILA, DOWN); dti_conn = UDPA_DISCONNECT_DTI; vsi_c_close (VSI_CALLER hCommHL); hCommHL = VSI_ERROR; /*XXX check for remaining UP/DOWN-LINK DTI connections, XXX*/ /*XXX terminate_ip() if noting left open XXX*/ } else if (udp_data->lola.link_id EQ udpa_dti_req->link_id) { dti_close ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_LL_INTERFACE, UDP_DTI_DEF_CHANNEL, FALSE ); *udp_data->lola.entity_name = 0; SET_STATE (LOLA, DOWN); dti_conn = UDPA_DISCONNECT_DTI; /*XXX check for remaining UP/DOWN-LINK DTI connections, XXX*/ /*XXX terminate_ip() if noting left open XXX*/ } else { TRACE_ERROR ("illegal parameter (udpa_dti_req->dti_conn)"); dti_conn = UDPA_CONNECT_DTI; } } break; } /* End switch (udpa_dti_req->dti_conn) */ break; } case ACTIVE_NC: switch (udpa_dti_req->dti_conn) { case UDPA_DISCONNECT_DTI: if (udp_data->hila.link_id EQ udpa_dti_req->link_id) { dti_close ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_HL_INTERFACE, UDP_DTI_DEF_CHANNEL, FALSE ); *udp_data->hila.entity_name = 0; SET_STATE (HILA, DOWN); dti_conn = UDPA_DISCONNECT_DTI; SET_STATE (KER, DEACTIVATED); vsi_c_close (VSI_CALLER hCommHL); hCommHL = VSI_ERROR; } else if (udp_data->lola.link_id EQ udpa_dti_req->link_id) { dti_close ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_LL_INTERFACE, UDP_DTI_DEF_CHANNEL, FALSE ); *udp_data->lola.entity_name = 0; SET_STATE (LOLA, DOWN); dti_conn = UDPA_DISCONNECT_DTI; SET_STATE (KER, DEACTIVATED); } break; default: TRACE_ERROR ("unexpected parameter (udpa_dti_req->dti_conn)"); dti_conn = UDPA_DISCONNECT_DTI; break; } /* End switch (udpa_dti_req->dti_conn) */ break; case CONNECTED: default: TRACE_ERROR ("unexpected UDPA_DTI_REQ"); if (udpa_dti_req->dti_conn EQ UDPA_CONNECT_DTI) dti_conn = UDPA_DISCONNECT_DTI; else dti_conn = UDPA_CONNECT_DTI; break; } /* End switch (GET_STATE (KER)) */ if (confirm) { PALLOC (udpa_dti_cnf, UDPA_DTI_CNF); udpa_dti_cnf->dti_conn = dti_conn; udpa_dti_cnf->link_id = udpa_dti_req->link_id; PSENDX (ACI, udpa_dti_cnf); } PFREE (udpa_dti_req); } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : UDP_KERP | | STATE : code ROUTINE : sig_dti_ker_tx_buffer_ready_ll_ind | +--------------------------------------------------------------------+ PURPOSE : Process signal SIG_DTI_KER_TX_BUFFER_READY_DN_IND */ void sig_dti_ker_tx_buffer_ready_ll_ind () { TRACE_FUNCTION ("sig_dti_ker_tx_buffer_ready_ll_ind()"); switch (GET_STATE (KER)) { case ACTIVE_NC: /* DTI_READY_IND not received yet */ SET_STATE (HILA, WAIT); break; case CONNECTED: { T_KER * p_ker = & udp_data->ker; T_HILA * p_ul = & udp_data->hila; /* Check if an ICMP message shall be sent */ if (p_ker->send_icmp) { T_DTI2_DATA_REQ * dti_data_req; p_ker->send_icmp = FALSE; if(p_ker->dti_data_req_icmp) { dti_data_req = p_ker->dti_data_req_icmp; p_ker->dti_data_req_icmp = NULL; } else { TRACE_ERROR("no ICMP message ready!"); return; } dti_data_req->parameters.p_id = DTI_PID_IP; dti_data_req->parameters.st_lines.st_flow = DTI_FLOW_ON; dti_data_req->parameters.st_lines.st_line_sa = DTI_SA_ON; dti_data_req->parameters.st_lines.st_line_sb = DTI_SB_ON; dti_data_req->parameters.st_lines.st_break_len = DTI_BREAK_OFF; PACCESS (dti_data_req); { PPASS (dti_data_req, dti_data_ind, DTI2_DATA_IND); dti_send_data ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_LL_INTERFACE, UDP_DTI_DEF_CHANNEL, dti_data_ind ); } /* Call dti_start to indicate ready */ dti_start ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_HL_INTERFACE, UDP_DTI_DEF_CHANNEL ); } /* If we have got a ready indication from LL - send dti_data_req */ else if (GET_STATE (HILA) EQ SEND AND p_ul->dti_data_req) { p_ul->dti_data_req->parameters.p_id = DTI_PID_IP; p_ul->dti_data_req->parameters.st_lines.st_flow = DTI_FLOW_ON; p_ul->dti_data_req->parameters.st_lines.st_line_sa = DTI_SA_ON; p_ul->dti_data_req->parameters.st_lines.st_line_sb = DTI_SB_ON; p_ul->dti_data_req->parameters.st_lines.st_break_len = DTI_BREAK_OFF; PACCESS (p_ul->dti_data_req); { PPASS (p_ul->dti_data_req, dti_data_ind, DTI2_DATA_IND); dti_send_data ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_LL_INTERFACE, UDP_DTI_DEF_CHANNEL, dti_data_ind ); } p_ul->dti_data_req = NULL; dti_start ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_HL_INTERFACE, UDP_DTI_DEF_CHANNEL ); } else { SET_STATE (HILA, WAIT); } } break; default: break; } } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : UDP_KERP | | STATE : code ROUTINE : sig_dti_ker_data_received_hl_ind | +--------------------------------------------------------------------+ PURPOSE : Process signal SIG_DTI_KER_DATA_RECEIVED_UP_IND */ void sig_dti_ker_data_received_hl_ind (T_DTI2_DATA_REQ * dti_data_req) { PACCESS (dti_data_req); TRACE_FUNCTION ("sig_dti_ker_data_received_hl_ind()"); switch (GET_STATE (KER)) { case CONNECTED: { T_HILA * p_ul = & udp_data->hila; T_KER * p_ker = & udp_data->ker; dti_stop ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_HL_INTERFACE, UDP_DTI_DEF_CHANNEL ); #ifdef _SIMULATION_ /* Get the T_SRC_DES out of the first and only descriptor * created by DTILIB and put it in a descriptor of its own */ if (dti_data_req->desc_list2.first && dti_data_req->desc_list2.list_len >= sizeof(T_SRC_DES)) { // The following is mostly taken from UDPa_sendRequest() from module // wap_udpc.c to achieve the same behaviour. (Issue UDP-FIX-21925) // The desc from the desc_list2 is splitted into a linked desc list // to simulate large data chunks (such large data chunks are spread over // in several decs in the list). T_desc2 *desc, *first_desc; ULONG *pLast; USHORT len, dataSize, data_length; const char *data_p; USHORT BLOCK_SIZE = 50; first_desc = (T_desc2 *) dti_data_req->desc_list2.first; data_length = dti_data_req->desc_list2.list_len; /* Build the T_desc2 for IP addresses and ports */ desc = M_ALLOC (offsetof (T_desc2, buffer) + sizeof (T_SRC_DES)); // update the desc list dti_data_req->desc_list2.first = (ULONG) desc; desc->offset = 0; desc->len = sizeof (T_SRC_DES); desc->size = sizeof (T_SRC_DES); // copy IP addresses and ports memcpy(desc->buffer, &first_desc->buffer[first_desc->offset],desc->len); /* Build the desc for the UDP data */ pLast = &desc->next; len = data_length - desc->len; data_p = &first_desc->buffer [first_desc->offset + desc->len];; while (len >0) { if (len > BLOCK_SIZE) { dataSize = BLOCK_SIZE; } else { dataSize = len; } MALLOC (desc, (USHORT)(sizeof(T_desc2) - 1 + dataSize)); memcpy( desc->buffer, data_p, dataSize); desc->offset = 0; desc->len = dataSize; desc->size = dataSize; len -= dataSize; data_p += dataSize; *pLast = (ULONG) desc; pLast = &desc->next; } MFREE (first_desc); } #endif /* _SIMULATION_ */ p_ul->dti_data_req = dti_data_req; if (p_ul->drop_packet) { p_ul->drop_packet = FALSE; PFREE_DESC2 (p_ul->dti_data_req); p_ul->dti_data_req = NULL; dti_start ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_LL_INTERFACE, UDP_DTI_DEF_CHANNEL ); } else { /* Get the IP addresses and the ports from HL */ T_desc2 * desc = (T_desc2 *) p_ul->dti_data_req->desc_list2.first; T_SRC_DES * p_SrcDes; USHORT old_len; if (desc == NULL) { TRACE_ERROR ( "Hila's T_desc2 is NULL in " "sig_dti_ker_data_received_hl_ind()." ); return; } p_SrcDes = (T_SRC_DES *) (desc->buffer + desc->offset); memcpy (& p_ker->src_addr, p_SrcDes->src_ip, 4); memcpy (& p_ker->dst_addr, p_SrcDes->des_ip, 4); memcpy (& p_ker->src_port, p_SrcDes->src_port, 2); memcpy (& p_ker->dst_port, p_SrcDes->des_port, 2); old_len = p_ul->dti_data_req->desc_list2.list_len; p_ul->dti_data_req->desc_list2.first = desc->next; p_ul->dti_data_req->desc_list2.list_len = (USHORT) (old_len - sizeof (T_SRC_DES)); p_ul = & udp_data->hila; MFREE (desc); } /* Send IP_ADDR_REQ to LL */ { PALLOC (ip_addr_req, IP_ADDR_REQ); ip_addr_req->dst_addr = p_ker->dst_addr; ip_addr_req->trans_prot = UDP_PROTOCOL; PSENDX (LL, ip_addr_req); } } break; default: PFREE_DESC2 (dti_data_req); break; } } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : udp_kerp.c | | STATE : code ROUTINE : ker_ip_addr_cnf | +--------------------------------------------------------------------+ PURPOSE : Process primitive T_IP_ADDR_CNF */ void ker_ip_addr_cnf (T_IP_ADDR_CNF * ip_addr_cnf) { TRACE_FUNCTION ("ker_ip_addr_cnf()"); PACCESS (ip_addr_cnf); switch (GET_STATE (KER)) { case CONNECTED: { T_KER * p_ker = & udp_data->ker; T_HILA * p_ul = & udp_data->hila; BOOL send_ready_ind = FALSE; /* No error ? */ if (ip_addr_cnf->err NEQ IP_ADDR_NOERROR) { PALLOC (udp_error_ind, UDP_ERROR_IND); udp_error_ind->dst_port = p_ker->dst_port; udp_error_ind->src_port = p_ker->src_port; udp_error_ind->err_msg = ip_addr_cnf->err; udp_error_ind->src_addr = ip_addr_cnf->src_addr; udp_error_ind->dst_addr = p_ker->dst_addr; PSENDX (HL, udp_error_ind); p_ul->drop_packet = TRUE; /* Packet error - drop it */ } /* Is the address correct ? */ else if (ip_addr_cnf->src_addr NEQ p_ker->src_addr) { PALLOC (udp_error_ind, UDP_ERROR_IND); udp_error_ind->dst_port = p_ker->dst_port; udp_error_ind->src_port = p_ker->src_port; udp_error_ind->err_msg = IP_ADDR_NOROUTE; udp_error_ind->src_addr = ip_addr_cnf->src_addr; udp_error_ind->dst_addr = p_ker->dst_addr; PSENDX (HL, udp_error_ind); p_ul->drop_packet = TRUE; /* Packet error - drop it */ } else /* Build the "standard" packet for higher layer */ { udp_build_packet (TRUE, B_NORMAL_PACKET); } /* ICMP sent at first */ if (p_ker->send_icmp && GET_STATE (HILA) EQ WAIT) { T_DTI2_DATA_REQ * dti_data_req; dti_data_req = p_ker->dti_data_req_icmp; dti_data_req->parameters.p_id = DTI_PID_IP; dti_data_req->parameters.st_lines.st_flow = DTI_FLOW_ON; dti_data_req->parameters.st_lines.st_line_sa = DTI_SA_ON; dti_data_req->parameters.st_lines.st_line_sb = DTI_SB_ON; dti_data_req->parameters.st_lines.st_break_len = DTI_BREAK_OFF; PACCESS (dti_data_req); { PPASS (dti_data_req, dti_data_ind, DTI2_DATA_IND); dti_send_data ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_LL_INTERFACE, UDP_DTI_DEF_CHANNEL, dti_data_ind ); } p_ker->dti_data_req_icmp = NULL; SET_STATE (HILA, SEND); /* Call dti_start to indicate ready for new packet */ dti_start ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_LL_INTERFACE, UDP_DTI_DEF_CHANNEL ); } /* Packet not correct - drop it */ if (p_ul->drop_packet) { p_ul->drop_packet = FALSE; PFREE_DESC2 (p_ul->dti_data_req); p_ul->dti_data_req = NULL; send_ready_ind = TRUE; } else { /* We have got a ready indication from LL -> send */ if (GET_STATE (HILA) EQ WAIT) /* Send dti_data_req packet */ { p_ul->dti_data_req->parameters.p_id = DTI_PID_IP; p_ul->dti_data_req->parameters.st_lines.st_flow = DTI_FLOW_ON; p_ul->dti_data_req->parameters.st_lines.st_line_sa = DTI_SA_ON; p_ul->dti_data_req->parameters.st_lines.st_line_sb = DTI_SB_ON; p_ul->dti_data_req->parameters.st_lines.st_break_len=DTI_BREAK_OFF; PACCESS (p_ul->dti_data_req); { PPASS (p_ul->dti_data_req, dti_data_ind, DTI2_DATA_IND); dti_send_data ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_LL_INTERFACE, UDP_DTI_DEF_CHANNEL, dti_data_ind ); } SET_STATE (HILA, IDLE); send_ready_ind = TRUE; p_ul->dti_data_req = NULL; } else { SET_STATE (HILA, SEND); send_ready_ind = FALSE; } } /* Send dti_ready indication */ if (send_ready_ind) { dti_start ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_HL_INTERFACE, UDP_DTI_DEF_CHANNEL ); } PFREE (ip_addr_cnf); } break; default: PFREE (ip_addr_cnf); break; } } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : udp_kerp.c | | STATE : code ROUTINE : sig_dti_ker_data_received_ll_ind | +--------------------------------------------------------------------+ PURPOSE : Process signal SIG_DTI_KER_DATA_RECEIVED_DN_IND */ void sig_dti_ker_data_received_ll_ind (T_DTI2_DATA_IND * dti_data_ind) { TRACE_FUNCTION ("sig_dti_ker_data_received_ll_ind()"); PACCESS (dti_data_ind); switch (GET_STATE (KER)) { case CONNECTED: { USHORT calc_chksum, header_chksum, start_udp, udp_len; UBYTE prot; BOOL send_getdata_req = FALSE; UBYTE * ip_header; T_desc_list2 * desc_list; T_desc2 * desc; T_KER * p_ker = & udp_data->ker; T_LOLA * p_dl = & udp_data->lola; dti_stop ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_LL_INTERFACE, UDP_DTI_DEF_CHANNEL ); /* Build necessary variable */ p_dl->dti_data_ind = dti_data_ind; p_dl->state_err = STATE_DL_NO_ERROR; desc_list = & p_dl->dti_data_ind->desc_list2; desc = (T_desc2 *) desc_list->first; if ( desc == NULL || desc->len < LEN_IP_HEADER_B || GET_IP_HEADER_LEN_B (desc->buffer + desc->offset) < LEN_IP_HEADER_B || desc->len < GET_IP_HEADER_LEN_B (desc->buffer + desc->offset) + LEN_UDP_HEADER_B ) { TRACE_ERROR ( "Lola's UDP packet is too short in " "sig_dti_ker_data_received_ll_ind()." ); return; } ip_header = desc->buffer + desc->offset; start_udp = (USHORT) GET_IP_HEADER_LEN_B (ip_header); /* Fill in port numbers and IP addresses */ p_dl->src_addr = GET_IP_SOURCE_ADDR (ip_header); p_dl->dst_addr = GET_IP_DEST_ADDR (ip_header); p_dl->src_port = (USHORT) GET_UDP_SRC_PORT (ip_header, start_udp); p_dl->dst_port = (USHORT) GET_UDP_DST_PORT (ip_header, start_udp); udp_len = (USHORT) GET_UDP_LEN (ip_header, start_udp); prot = GET_IP_PROT (ip_header); /* Check if ICMP Message, if yes - send UDP_ERROR_IND */ if (GET_IP_PROT (ip_header) EQ ICMP_PROT) { USHORT pos_icmp = (USHORT) GET_IP_HEADER_LEN_B (ip_header); p_dl->drop_packet = TRUE; p_dl->state_err = STATE_DL_ERROR; { PALLOC (udp_error_ind, UDP_ERROR_IND); udp_error_ind->dst_port = p_dl->dst_port; udp_error_ind->src_port = p_dl->src_port; udp_error_ind->err_msg = GET_ICMP_TYPE (ip_header, pos_icmp); udp_error_ind->src_addr = GET_IP_SOURCE_ADDR (ip_header); udp_error_ind->dst_addr = GET_IP_DEST_ADDR (ip_header); PSENDX (HL, udp_error_ind); } } else /* No ICMP_PROT */ { { ULONG overlay; UBYTE pseudo_header [LEN_PSEUDO_HEADER_B]; /* Build the pseudoheader for the calculation of the checksum */ SET_UDP_PSEUDO_H_SRC_ADDR (pseudo_header, p_dl->src_addr); SET_UDP_PSEUDO_H_DEST_ADDR (pseudo_header, p_dl->dst_addr); SET_UDP_PSEUDO_H_ZERO (pseudo_header, 0); SET_UDP_PSEUDO_H_PROT (pseudo_header, prot); SET_UDP_PSEUDO_H_LEN (pseudo_header, udp_len); /* Calculate a part of the checksum for the pseudoheader */ overlay = partial_checksum (pseudo_header, LEN_PSEUDO_HEADER_B); /* Calculate for the UDP header and the data */ header_chksum = (USHORT) GET_UDP_CHK_SUM (ip_header, start_udp); RESET_UDP_CHKSUM (ip_header, start_udp); calc_chksum = desc_checksum (desc_list, start_udp, overlay); SET_UDP_CHKSUM (ip_header, start_udp, header_chksum); } /* Packet checksum error ? */ if (header_chksum NEQ calc_chksum) { p_dl->drop_packet = TRUE; } else { #define POS_UDP_DEST_PORT 1 /* Is it the correct port ? */ if (p_ker->src_port EQ p_dl->dst_port) { udp_build_packet (FALSE, B_NORMAL_PACKET); } else { /* Build ICMP packet for no dest port. * If LL is ready to collect then send */ udp_build_packet (FALSE, B_NO_DEST_PORT); p_ker->send_icmp = TRUE; } } } /* No ICMP_PROT */ /* Packet is not correct -> drop it and free the primitive */ if (p_dl->drop_packet) { p_dl->drop_packet = FALSE; PFREE_DESC2 (p_dl->dti_data_ind); p_dl->dti_data_ind = NULL; send_getdata_req = TRUE; } else { /* An ICMP message - send it */ if (p_ker->send_icmp) { UBYTE state = GET_STATE (LOLA); if (state EQ IDLE OR state EQ WAIT) { T_DTI2_DATA_REQ * dti_data_req; udp_data->ker.send_icmp = FALSE; dti_data_req = p_ker->dti_data_req_icmp; dti_data_req->parameters.p_id = DTI_PID_IP; dti_data_req->parameters.st_lines.st_flow = DTI_FLOW_ON; dti_data_req->parameters.st_lines.st_line_sa = DTI_SA_ON; dti_data_req->parameters.st_lines.st_line_sb = DTI_SB_ON; dti_data_req->parameters.st_lines.st_break_len = DTI_BREAK_OFF; PACCESS (dti_data_req); { PPASS (dti_data_req, dti_data_indication, DTI2_DATA_IND); dti_send_data ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_LL_INTERFACE, UDP_DTI_DEF_CHANNEL, dti_data_indication ); } SET_STATE (LOLA, IDLE); p_ker->dti_data_req_icmp = NULL; send_getdata_req = TRUE; } } else { /* We have got a DTI2_GETDATA_REQ from LL. Send the packet. */ if (GET_STATE (LOLA) EQ WAIT) { SET_STATE (LOLA, IDLE); p_dl->dti_data_ind->parameters.p_id = DTI_PID_IP; p_dl->dti_data_ind->parameters.st_lines.st_flow = DTI_FLOW_ON; p_dl->dti_data_ind->parameters.st_lines.st_line_sa = DTI_SA_ON; p_dl->dti_data_ind->parameters.st_lines.st_line_sb = DTI_SB_ON; p_dl->dti_data_ind->parameters.st_lines.st_break_len = DTI_BREAK_OFF; dti_send_data ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_HL_INTERFACE, UDP_DTI_DEF_CHANNEL, p_dl->dti_data_ind ); send_getdata_req = TRUE; p_dl->dti_data_ind = NULL; } else { SET_STATE (LOLA, SEND); } } } if (send_getdata_req) /* Send DTI2_GETDATA_REQ to LL */ { dti_start ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_LL_INTERFACE, UDP_DTI_DEF_CHANNEL ); } } break; default: PFREE_DESC2 (dti_data_ind); break; } } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : udp_kerp.c | | STATE : code ROUTINE : sig_dti_ker_tx_buffer_ready_hl_ind | +--------------------------------------------------------------------+ PURPOSE : Process signal SIG_DTI_KER_TX_BUFFER_READY_UP_IND */ void sig_dti_ker_tx_buffer_ready_hl_ind () { TRACE_FUNCTION ("sig_dti_ker_tx_buffer_ready_hl_ind()"); switch (GET_STATE (KER)) { case CONNECTED: { T_KER * p_ker = & udp_data->ker; T_LOLA * p_dl = & udp_data->lola; /* We have bound a port and got a DTI_GETDATA_REQ */ if (p_ker->port_state EQ PORT_BOUND) { p_ker->port_state = PORT_ACTIVE; dti_start ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_HL_INTERFACE, UDP_DTI_DEF_CHANNEL ); } /* Send dti_data_ind packet if we have one */ if (GET_STATE (LOLA) EQ SEND) { p_dl->dti_data_ind->parameters.p_id = DTI_PID_IP; p_dl->dti_data_ind->parameters.st_lines.st_flow = DTI_FLOW_ON; p_dl->dti_data_ind->parameters.st_lines.st_line_sa = DTI_SA_ON; p_dl->dti_data_ind->parameters.st_lines.st_line_sb = DTI_SB_ON; p_dl->dti_data_ind->parameters.st_lines.st_break_len = DTI_BREAK_OFF; dti_send_data ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_HL_INTERFACE, UDP_DTI_DEF_CHANNEL, p_dl->dti_data_ind ); p_dl->dti_data_ind = NULL; SET_STATE (LOLA, IDLE); /* Send DTI2_GETDATA_REQ and indicate ready for new packet */ dti_start ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_LL_INTERFACE, UDP_DTI_DEF_CHANNEL ); } else { /* No data packet to be sent - change state */ SET_STATE (LOLA, WAIT); } } break; default: break; } } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : udp_kerp.c | | STATE : code ROUTINE : ker_udp_bind_cnf | +--------------------------------------------------------------------+ PURPOSE : Process primitive T_UDP_BIND_CNF */ static void ker_udp_bind_cnf (U16 port, U8 err) { PALLOC (udp_bind_cnf, UDP_BIND_CNF); TRACE_FUNCTION ("ker_udp_bind_cnf()"); udp_bind_cnf->port = port; udp_bind_cnf->err = err; PSENDX (HL, udp_bind_cnf); } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : udp_kerp.c | | STATE : code ROUTINE : ker_udp_bind_req | +--------------------------------------------------------------------+ PURPOSE : Process primitive T_UDP_BIND_REQ */ void ker_udp_bind_req (T_UDP_BIND_REQ * udp_bind_req) { TRACE_FUNCTION ("ker_udp_bind_req()"); PACCESS (udp_bind_req); switch (GET_STATE (KER)) { case ACTIVE_NC: ker_udp_bind_cnf (udp_bind_req->port, UDP_BIND_UDPDOWN); break; case CONNECTED: { T_KER * p_ker = & udp_data->ker; if (p_ker->port_state EQ PORT_DOWN) { if (udp_bind_req->port EQ NO_PORT) { p_ker->src_port = 1025; } else { p_ker->src_port = udp_bind_req->port; } p_ker->port_state = PORT_BOUND; ker_udp_bind_cnf (p_ker->src_port, UDP_BIND_NOERROR); } else /* Port in use */ { ker_udp_bind_cnf (udp_bind_req->port, UDP_BIND_PORTINUSE); } } break; case DEACTIVATED: TRACE_ERROR ("unexpected UDP_BIND_REQ"); break; default: break; } PFREE (udp_bind_req); } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : udp_kerp.c | | STATE : code ROUTINE : ker_udp_closeport_req | +--------------------------------------------------------------------+ PURPOSE : Process primitive T_UDP_CLOSEPORT_REQ */ void ker_udp_closeport_req (T_UDP_CLOSEPORT_REQ * udp_closeport_req) { T_KER * p_ker; TRACE_FUNCTION ("ker_udp_closeport_req()"); PACCESS (udp_closeport_req); p_ker = & udp_data->ker; switch (GET_STATE (KER)) { case ACTIVE_NC: case CONNECTED: /* Close port */ p_ker->src_port = NO_PORT; p_ker->port_state = PORT_DOWN; { PALLOC (udp_closeport_cnf, UDP_CLOSEPORT_CNF); PSENDX (HL, udp_closeport_cnf); } break; case DEACTIVATED: TRACE_ERROR ("unexpected UDP_CLOSEPORT_REQ"); break; default: break; } PFREE (udp_closeport_req); } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : udp_kerp.c | | STATE : code ROUTINE : ker_udp_error_res | +--------------------------------------------------------------------+ PURPOSE : Process primitive T_UDP_ERROR_RES */ void ker_udp_error_res (T_UDP_ERROR_RES * udp_error_res) { TRACE_FUNCTION ("ker_udp_error_res()"); PACCESS (udp_error_res); /* Confirm the error message from ACI */ switch (GET_STATE (KER)) { case CONNECTED: { T_LOLA * p_dl = & udp_data->lola; if (p_dl->state_err EQ STATE_DL_ERROR) p_dl->state_err = STATE_DL_NO_ERROR; else dti_start ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_LL_INTERFACE, UDP_DTI_DEF_CHANNEL ); } break; default: break; } PFREE (udp_error_res); } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : UDP_KERP | | STATE : code ROUTINE : sig_dti_ker_connection_opened_hl_ind | +--------------------------------------------------------------------+ PURPOSE : Process signal sig_dti_ker_connection_opened_hl_ind */ void sig_dti_ker_connection_opened_hl_ind () { TRACE_FUNCTION ("sig_dti_ker_connection_opened_hl_ind()"); if (GET_STATE (HILA) EQ CONNECTING) { UBYTE state = GET_STATE (LOLA); SET_STATE (HILA, IDLE); if (state NEQ CONNECTING AND state NEQ DOWN) { SET_STATE (KER, ACTIVE_NC); } { PALLOC (udpa_dti_cnf, UDPA_DTI_CNF); udpa_dti_cnf->link_id = udp_data->hila.link_id; udpa_dti_cnf->dti_conn = UDPA_CONNECT_DTI; PSENDX (ACI, udpa_dti_cnf); } } else { TRACE_ERROR ("unexpected dti_connect_ind (from higher layer)"); } } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : UDP_KERP | | STATE : code ROUTINE : sig_dti_ker_connection_opened_ll_ind | +--------------------------------------------------------------------+ PURPOSE : Process signal sig_dti_ker_connection_opened_ll_ind */ void sig_dti_ker_connection_opened_ll_ind () { TRACE_FUNCTION ("sig_dti_ker_connection_opened_ll_ind()"); if (GET_STATE (LOLA) EQ CONNECTING) { UBYTE state = GET_STATE (HILA); SET_STATE (LOLA, IDLE); if (state NEQ CONNECTING AND state NEQ DOWN) { SET_STATE (KER, ACTIVE_NC); } { PALLOC (udpa_dti_cnf, UDPA_DTI_CNF); udpa_dti_cnf->link_id = udp_data->lola.link_id; udpa_dti_cnf->dti_conn = UDPA_CONNECT_DTI; PSENDX (ACI, udpa_dti_cnf); } } else { TRACE_ERROR ("unexpected dti_connect_ind (from lower layer)"); } } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : udp_kerp.c | | STATE : code ROUTINE : ker_udp_shutdown_ind | +--------------------------------------------------------------------+ PURPOSE : */ static void ker_udpa_dti_ind (ULONG link_id) { PALLOC (udpa_dti_ind, UDPA_DTI_IND); udpa_dti_ind->link_id = link_id; PSENDX (ACI, udpa_dti_ind); } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : udp_kerp.c | | STATE : code ROUTINE : ker_udp_shutdown_ind | +--------------------------------------------------------------------+ PURPOSE : */ static void ker_udp_shutdown_ind (void) { PALLOC (udp_shutdown_ind, UDP_SHUTDOWN_IND); PSENDX (HL, udp_shutdown_ind); } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : udp_kerp.c | | STATE : code ROUTINE : check_port_shutdown_ind | +--------------------------------------------------------------------+ PURPOSE : */ static void check_port_shutdown_ind (void) { T_KER * p_ker = & udp_data->ker; TRACE_FUNCTION ("check_port_shutdown_ind()"); if (p_ker->port_state EQ PORT_ACTIVE) { p_ker->src_port = NO_PORT; p_ker->port_state = PORT_DOWN; ker_udp_shutdown_ind (); } } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : UDP_KERP | | STATE : code ROUTINE : sig_dti_ker_connection_closed_hl_ind | +--------------------------------------------------------------------+ PURPOSE : Process signal sig_dti_ker_connection_closed_hl_ind */ void sig_dti_ker_connection_closed_hl_ind () { TRACE_FUNCTION ("sig_dti_ker_connection_closed_hl_ind()"); switch (GET_STATE (KER)) { case CONNECTED: /*XXX bad case, switch to DEACTIVATED, prune buffers... XXX*/ TRACE_ERROR ("unexpected DTI connection close from higher layer"); check_port_shutdown_ind (); SET_STATE (KER, DEACTIVATED); break; case ACTIVE_NC: SET_STATE (KER, DEACTIVATED); break; default: break; } vsi_c_close (VSI_CALLER hCommHL); hCommHL = VSI_ERROR; SET_STATE (HILA, DOWN); *udp_data->hila.entity_name = 0; ker_udpa_dti_ind (udp_data->hila.link_id); } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : UDP_KERP | | STATE : code ROUTINE : sig_dti_ker_connection_closed_ll_ind | +--------------------------------------------------------------------+ PURPOSE : Process signal sig_dti_ker_connection_closed_ll_ind */ void sig_dti_ker_connection_closed_ll_ind () { TRACE_FUNCTION ("sig_dti_ker_connection_closed_ll_ind()"); switch (GET_STATE (KER)) { case CONNECTED: /*XXX bad case, switch to DEACTIVATED, prune buffers... XXX*/ TRACE_ERROR ("unexpected DTI connection close from lower layer"); check_port_shutdown_ind (); SET_STATE (KER, DEACTIVATED); break; case ACTIVE_NC: SET_STATE (KER, DEACTIVATED); break; default: break; } SET_STATE (LOLA, DOWN); *udp_data->lola.entity_name = 0; ker_udpa_dti_ind (udp_data->lola.link_id); } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : udp_kerp.c | | STATE : code ROUTINE : ker_udpa_config_req | +--------------------------------------------------------------------+ PURPOSE : Process primitive T_UDPA_CONFIG_REQ */ void ker_udpa_config_req (T_UDPA_CONFIG_REQ * udpa_config_req) { TRACE_FUNCTION ("ker_udpa_config_req()"); PACCESS (udpa_config_req); /* Configuration of lower layer -> change to state CONNECTED */ switch (GET_STATE (KER)) { case CONNECTED: switch (udpa_config_req->cmd) { case UDPA_CONFIG_DOWN: check_port_shutdown_ind (); SET_STATE (KER, ACTIVE_NC); { PALLOC (udpa_config_cnf, UDPA_CONFIG_CNF); PSENDX (ACI, udpa_config_cnf); } break; default: break; } break; case ACTIVE_NC: switch (udpa_config_req->cmd) { case UDPA_CONFIG_UP: dti_start ( udp_hDTI, UDP_DTI_DEF_INSTANCE, UDP_DTI_LL_INTERFACE, UDP_DTI_DEF_CHANNEL ); SET_STATE (KER, CONNECTED); TRACE_EVENT ("KER -> CONNECTED"); { PALLOC (udpa_config_cnf, UDPA_CONFIG_CNF); PSENDX (ACI, udpa_config_cnf); } break; case UDPA_CONFIG_DOWN: { PALLOC (udpa_config_cnf, UDPA_CONFIG_CNF); PSENDX (ACI, udpa_config_cnf); } break; default: break; } break; default: break; } PFREE (udpa_config_req); } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : udp_kerp.c | | STATE : code ROUTINE : ker_udp_shutdown_res | +--------------------------------------------------------------------+ PURPOSE : Process primitive T_UDP_SHUTDOWN_RES */ void ker_udp_shutdown_res (T_UDP_SHUTDOWN_RES * udp_shutdown_res) { TRACE_FUNCTION ("DUMMY ker_udp_shutdown_res()"); PACCESS (udp_shutdown_res); PFREE (udp_shutdown_res); } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : udp_kerp.c | | STATE : code ROUTINE : sig_dti_ker_tx_buffer_full_hl_ind | +--------------------------------------------------------------------+ PURPOSE : Process signal SIG_DTI_KER_TX_BUFFER_FULL_UP_IND */ void sig_dti_ker_tx_buffer_full_hl_ind () { TRACE_FUNCTION ("DUMMY sig_dti_ker_tx_buffer_full_hl_ind()"); } /* +--------------------------------------------------------------------+ | PROJECT : WAP MODULE : UDP_KERP | | STATE : code ROUTINE : sig_dti_ker_tx_buffer_full_ll_ind | +--------------------------------------------------------------------+ PURPOSE : Process signal SIG_DTI_KER_TX_BUFFER_FULL_DN_IND */ void sig_dti_ker_tx_buffer_full_ll_ind () { TRACE_FUNCTION ("DUMMY sig_dti_ker_tx_buffer_full_ll_ind()"); } /*-------------------------------------------------------------------------*/