FreeCalypso > hg > fc-magnetite
view src/g23m-fad/udp/udp_kerp.c @ 636:57e67ca2e1cb
pcmdata.c: default +CGMI to "FreeCalypso" and +CGMM to model
The present change has no effect whatsoever on Falconia-made and Openmoko-made
devices on which /pcm/CGMI and /pcm/CGMM files have been programmed in FFS
with sensible ID strings by the respective factories, but what should AT+CGMI
and AT+CGMM queries return when the device is a Huawei GTM900 or Tango modem
that has been converted to FreeCalypso with a firmware change? Before the
present change they would return compiled-in defaults of "<manufacturer>" and
"<model>", respectively; with the present change the firmware will self-identify
as "FreeCalypso GTM900-FC" or "FreeCalypso Tango" on the two respective targets.
This firmware identification will become important if someone incorporates an
FC-converted GTM900 or Tango modem into a ZeroPhone-style smartphone where some
high-level software like ofono will be talking to the modem and will need to
properly identify this modem as FreeCalypso, as opposed to some other AT command
modem flavor with different quirks.
In technical terms, the compiled-in default for the AT+CGMI query (which will
always be overridden by the /pcm/CGMI file in FFS if one is present) is now
"FreeCalypso" in all configs on all targets; the compiled-in default for the
AT+CGMM query (likewise always overridden by /pcm/CGMM if present) is
"GTM900-FC" if CONFIG_TARGET_GTM900 or "Tango" if CONFIG_TARGET_TANGO or the
original default of "<model>" otherwise.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 19 Jan 2020 20:14:58 +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()"); } /*-------------------------------------------------------------------------*/