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()");
}
/*-------------------------------------------------------------------------*/