FreeCalypso > hg > fc-tourmaline
view src/g23m-fad/udp/udp_kerp.c @ 78:c632896652ba
mfw/ti1_key.c: properly initialize notified_keys array
The code in this ti1_key.c layer needs to call kpd_subscribe() and
kpd_define_key_notification() functions in order to register with the
KPD driver. The original code passed KPD_NB_PHYSICAL_KEYS in
nb_notified_keys - this constant is defined to 24 in kpd_cfg.h on all
platforms of interest to us - but it only filled the first 23 slots
in the notified_keys array, resulting in stack garbage being passed
to KPD API functions. The fix consists of initializing the last
missed array slot to KPD_KEY_RECORD, the key ID for the right side
button on the D-Sample handset.
On our current hw targets this "Record" button exists as the EXTRA
button on our Luna keypad board and as the camera button on the
Pirelli DP-L10. There is no support whatsoever for this button
in current BMI+MFW, we have no plans of doing anything with Pirelli's
camera button even if we do get our UI fw running on that phone,
and the Mother's dream of building our own FreeCalypso handset with
the same button arrangement as D-Sample (including the right side
button) is currently very nebulous - but let us nonetheless handle
the full set of buttons on the KPD to MFW interface, and let upper
layers weed out unsupported buttons.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 25 Oct 2020 23:41:01 +0000 |
parents | fa8dc04885d8 |
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()"); } /*-------------------------------------------------------------------------*/