FreeCalypso > hg > fc-tourmaline
diff src/g23m-gprs/sndcp/sndcp_f.c @ 1:fa8dc04885d8
src/g23m-*: import from Magnetite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 16 Oct 2020 06:25:50 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/g23m-gprs/sndcp/sndcp_f.c Fri Oct 16 06:25:50 2020 +0000 @@ -0,0 +1,3027 @@ +/* ++----------------------------------------------------------------------------- +| Project : GPRS (8441) +| Modul : sndcp_f.c ++----------------------------------------------------------------------------- +| 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 : Contains global functions of SNDCP ++----------------------------------------------------------------------------- +*/ + +#define ENTITY_SNDCP + +/*==== INCLUDES =============================================================*/ + +#include "typedefs.h" /* to get Condat data types */ +#include "vsi.h" /* to get a lot of macros */ +#include "gsm.h" /* to get a lot of macros */ +#include "prim.h" /* to get the definitions of used SAP and directions */ +#include "macdef.h" + +#include "dti.h" +#include "sndcp.h" /* to get the global entity definitions */ +#include "sndcp_f.h" /* to get the functions to access the global arrays*/ + +#include "sndcp_nup.h" /* to get nu functions that will be called from + sndcp_sig_callback() */ +#include "sndcp_ndp.h" /* to get nu functions that will be called from + sndcp_sig_callback() */ + + +#include <string.h> /* to get memcpy() */ + + +/*==== CONST ================================================================*/ + +#ifdef SNDCP_TRACE_IP_DATAGRAM +#ifndef CF_FAST_EXEC +static U8 bin_trace_ip_buf[1500]; +#endif /* CF_FAST_EXEC */ +#endif +/*==== LOCAL VARS ===========================================================*/ + + + + +#ifdef TI_PS_OP_ICUT_SNDCP + +/* PDP_TBR add SNDCP terminal loopback capability */ +extern U8 SNDCP_LOOPBACK; +extern BOOL bufFull[SNDCP_NUMBER_OF_NSAPIS]; +extern T_DTI2_DATA_IND *saveDti2_data_ind[SNDCP_NUMBER_OF_NSAPIS] ; + +#endif /* TI_PS_OP_ICUT_SNDCP */ + + + + + +/*==== PRIVATE FUNCTIONS ====================================================*/ + +/*==== PUBLIC FUNCTIONS =====================================================*/ + + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_nsapi_ack ++------------------------------------------------------------------------------ +| Description : gets nsapi_ack_ra[nsapi] +| +| Parameters : UBYTE nsapi, BOOL* ack +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_get_nsapi_ack(UBYTE nsapi, + BOOL* ack) +{ + TRACE_FUNCTION("sndcp_get_nsapi_ack"); + { + *ack = sndcp_data->nsapi_ack_ra[nsapi]; + } +} + +#endif /* CF_FAST_EXEC */ + +#ifdef _SNDCP_DTI_2_ +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_nsapi_direction ++------------------------------------------------------------------------------ +| Description : gets nsapi_ack_direction[nsapi] +| Values: HOME or NEIGHBOR from dti.h. +| +| Parameters : UBYTE nsapi, BOOL* direction +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_get_nsapi_direction(UBYTE nsapi, + U8* direction) +{ + TRACE_FUNCTION("sndcp_get_nsapi_direction"); + { + *direction = (U8)sndcp_data->nsapi_direction_ra[nsapi]; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_nsapi_interface ++------------------------------------------------------------------------------ +| Description : gets nsapi_interface_ra[nsapi] +| +| Parameters : UBYTE nsapi, U8 interface +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_get_nsapi_interface(UBYTE nsapi, + U8* interfac) +{ + TRACE_FUNCTION("sndcp_get_nsapi_interface"); + { + *interfac = sndcp_data->nsapi_interface_ra[nsapi]; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_nsapi_linkid ++------------------------------------------------------------------------------ +| Description : gets nsapi_linkid_ra[nsapi] +| +| Parameters : UBYTE nsapi, ULONG* linkid +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_get_nsapi_linkid(UBYTE nsapi, + ULONG* linkid) +{ + TRACE_FUNCTION("sndcp_get_nsapi_linkid"); + { + *linkid = sndcp_data->nsapi_linkid_ra[nsapi]; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_nsapi_neighbor ++------------------------------------------------------------------------------ +| Description : gets nsapi_neighbor_ra[nsapi] +| +| Parameters : UBYTE nsapi, UBYTE** neighbor +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_get_nsapi_neighbor(UBYTE nsapi, + UBYTE** neighbor) +{ + TRACE_FUNCTION("sndcp_get_nsapi_neighbor"); + { + *neighbor = sndcp_data->nsapi_neighbor_ra[nsapi]; + } +} +#endif /* CF_FAST_EXEC */ + +#else /*_SNDCP_DTI_2_*/ +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_nsapi_direction ++------------------------------------------------------------------------------ +| Description : gets nsapi_ack_direction[nsapi] +| Values: HOME or NEIGHBOR from dti.h. +| +| Parameters : UBYTE nsapi, BOOL* direction +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_get_nsapi_direction(UBYTE nsapi, + BOOL* direction) +{ + TRACE_FUNCTION("sndcp_get_nsapi_direction"); + { + *direction = sndcp_data->nsapi_direction_ra[nsapi]; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_nsapi_interface ++------------------------------------------------------------------------------ +| Description : gets nsapi_interface_ra[nsapi] +| +| Parameters : UBYTE nsapi, U8 interface +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_get_nsapi_interface(UBYTE nsapi, + U8* interfac) +{ + TRACE_FUNCTION("sndcp_get_nsapi_interface"); + { + *interfac = sndcp_data->nsapi_interface_ra[nsapi]; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_nsapi_linkid ++------------------------------------------------------------------------------ +| Description : gets nsapi_linkid_ra[nsapi] +| +| Parameters : UBYTE nsapi, ULONG* linkid +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_get_nsapi_linkid(UBYTE nsapi, + ULONG* linkid) +{ + TRACE_FUNCTION("sndcp_get_nsapi_linkid"); + { + *linkid = sndcp_data->nsapi_linkid_ra[nsapi]; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_nsapi_neighbor ++------------------------------------------------------------------------------ +| Description : gets nsapi_neighbor_ra[nsapi] +| +| Parameters : UBYTE nsapi, UBYTE** neighbor +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_get_nsapi_neighbor(UBYTE nsapi, + UBYTE** neighbor) +{ + TRACE_FUNCTION("sndcp_get_nsapi_neighbor"); + { + *neighbor = sndcp_data->nsapi_neighbor_ra[nsapi]; + } +} + +#endif /* CF_FAST_EXEC */ + +#endif /*_SNDCP_DTI_2_*/ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_sapi_ack ++------------------------------------------------------------------------------ +| Description : gets sapi_ack_ra["index of sapi"] +| +| Parameters : UBYTE sapi, BOOL* ack +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_get_sapi_ack(UBYTE sapi, + BOOL* ack) +{ + TRACE_FUNCTION("sndcp_get_sapi_ack"); + { + UBYTE sapi_index = 0; + + sndcp_get_sapi_index(sapi, &sapi_index); + *ack = sndcp_data->sapi_ack_ra[sapi_index]; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_sapi_stat ++------------------------------------------------------------------------------ +| Description : gets sapi_state_ra[sapi] +| +| Parameters : UBYTE sapi, UBYTE* stat +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_get_sapi_state(UBYTE sapi, + USHORT* stat) +{ + TRACE_FUNCTION("sndcp_get_sapi_state"); + { + UBYTE sapi_index = 0; + + sndcp_get_sapi_index(sapi, &sapi_index); + *stat = sndcp_data->sapi_state_ra[sapi_index]; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_sapi_index ++------------------------------------------------------------------------------ +| Description : gets the index (0, 1, 2, 3) for the given sapi (3, 5, 9, 11). +| This function is used when a sapi number serves as a key for one of the 4 +| possible instances of services su and sd. +| +| Parameters : UBYTE sapi, UBYTE* index +| ++------------------------------------------------------------------------------ +*/ +/*#if defined(CF_FAST_EXEC) || defined(_SIMULATION_) || \ + defined(SNDCP_2to1) */ + +GLOBAL void sndcp_get_sapi_index(UBYTE sapi, + UBYTE* index) +{ + TRACE_FUNCTION("sndcp_get_sapi_index"); + { + if (sapi == 3) { + *index = 0; + } else if (sapi == 5) { + *index = 1; + } else if (sapi == 9) { + *index = 2; + } else if (sapi == 11) { + *index = 3; + } + } +} + +/*#endif */ /* CF_FAST_EXEC || _SIMULATION_ || !REL99 || SNDCP_2to1 */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_nsapi_prio ++------------------------------------------------------------------------------ +| Description : sets prio to nsapi_prio_ra[nsapi] +| +| Parameters : UBYTE nsapi, UBYTE* prio +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_get_nsapi_prio(UBYTE nsapi, + UBYTE* prio) +{ + TRACE_FUNCTION("sndcp_get_nsapi_prio"); + { + *prio = sndcp_data->nsapi_prio_ra[nsapi]; + } +} + +#endif /* CF_FAST_EXEC */ + +#ifdef REL99 +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_nsapi_pktflowid ++------------------------------------------------------------------------------ +| Description : gets packet flow id form nsapi_pktflowid_ra[nsapi] +| +| Parameters : UBYTE nsapi, UBYTE* pkt_flow_id +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_get_nsapi_pktflowid(U8 nsapi, U16* pkt_flow_id) + +{ + TRACE_FUNCTION("sndcp_get_nsapi_pktflowid"); + { + *pkt_flow_id = sndcp_data->nsapi_pktflowid_ra[nsapi]; + } +} + +#endif /* CF_FAST_EXEC */ + +#endif /*REL99*/ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_nsapi_qos ++------------------------------------------------------------------------------ +| Description : gets nsapi_qos_ra[nsapi] +| +| Parameters : UBYTE nsapi, T_snsm_qos* qos +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_get_nsapi_qos(UBYTE nsapi, + T_snsm_qos* qos) +{ + TRACE_FUNCTION("sndcp_get_nsapi_qos"); + { + qos->delay = sndcp_data->nsapi_qos_ra[nsapi].delay; + qos->relclass = sndcp_data->nsapi_qos_ra[nsapi].relclass; + qos->peak = sndcp_data->nsapi_qos_ra[nsapi].peak; + qos->preced = sndcp_data->nsapi_qos_ra[nsapi].preced; + qos->mean = sndcp_data->nsapi_qos_ra[nsapi].mean; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_nsapi_sapi ++------------------------------------------------------------------------------ +| Description : gets nsapi_sapi_ra[nsapi] +| +| Parameters : UBYTE nsapi, UBYTE* sapi +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_get_nsapi_sapi(UBYTE nsapi, + UBYTE* sapi) +{ + TRACE_FUNCTION("sndcp_get_nsapi_sapi"); + { + *sapi = sndcp_data->nsapi_sapi_ra[nsapi]; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_nsapi_state ++------------------------------------------------------------------------------ +| Description : gets nsapi_state_ra[nsapi] +| +| Parameters : UBYTE nsapi, USHORT* state +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_get_nsapi_state(UBYTE nsapi, + USHORT* state) +{ + TRACE_FUNCTION("sndcp_get_nsapi_state"); + { + *state = sndcp_data->nsapi_state_ra[nsapi]; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_is_nsapi_data_compressed ++------------------------------------------------------------------------------ +| Description : If nsapi uses data compression then compressed is set to TRUE, +| else to FALSE. +| +| Parameters : UBYTE nsapi, BOOL* compressed +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_is_nsapi_data_compressed(UBYTE nsapi, + BOOL* compressed) +{ + USHORT nsapis = sndcp_data->cia.cur_xid_block.v42.nsapis; + + TRACE_FUNCTION("sndcp_is_nsapi_data_compressed"); + + *compressed = (nsapis & (1 << nsapi)) > 0; + +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_is_nsapi_used ++------------------------------------------------------------------------------ +| Description : sets b to TRUE if the nsapi is already in use, otherwise to +| FALSE +| +| Parameters : UBYTE nsapi, BOOL* b +| ++------------------------------------------------------------------------------ +*/ +/*#if defined(CF_FAST_EXEC) || defined(_SIMULATION_) || \ + defined (SNDCP_2to1) */ + +GLOBAL void sndcp_is_nsapi_used(UBYTE nsapi, + BOOL* b) +{ + TRACE_FUNCTION("sndcp_is_nsapi_used"); + { + *b = sndcp_data->nsapi_used_ra[nsapi]; + } +} + +/*#endif */ /* CF_FAST_EXEC || _SIMULATION_ || !REL99 || SNDCP_2to1 */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_is_nsapi_header_compressed ++------------------------------------------------------------------------------ +| Description : If nsapi uses header compression then compressed is set to TRUE, +| else to FALSE. +| +| Parameters : UBYTE nsapi, BOOL* compressed +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_is_nsapi_header_compressed(UBYTE nsapi, + BOOL* compressed) +{ + USHORT nsapis = sndcp_data->cia.cur_xid_block.vj.nsapis; + + TRACE_FUNCTION("sndcp_is_nsapi_header_compressed"); + + *compressed = ((nsapis & (1 << nsapi)) > 0) && + sndcp_data->cia.cur_xid_block.vj.is_set; + +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_mean_trace ++------------------------------------------------------------------------------ +| Description : traces the mean thruput for given +| +| Parameters : nsapi, direction, ack_mode +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_mean_trace(UBYTE nsapi, + UBYTE direction, + UBYTE ack_mode, + USHORT len) +{ + T_TIME* start_time_ra = NULL; + T_TIME* cur_time_ra = NULL; + ULONG* cur_num_ra = NULL; + ULONG* cur_pac_ra = NULL; + + TRACE_FUNCTION("sndcp_mean_trace"); + + if (direction == SNDCP_MEAN_UP) { + if (ack_mode == SNDCP_MEAN_ACK) { + start_time_ra = sndcp_data->start_time_uplink_ack; + cur_time_ra = sndcp_data->cur_time_uplink_ack; + cur_num_ra = sndcp_data->cur_num_uplink_ack; + cur_pac_ra = sndcp_data->cur_pac_uplink_ack; + } else { + start_time_ra = sndcp_data->start_time_uplink_unack; + cur_time_ra = sndcp_data->cur_time_uplink_unack; + cur_num_ra = sndcp_data->cur_num_uplink_unack; + cur_pac_ra = sndcp_data->cur_pac_uplink_unack; + } + } else { + if (ack_mode == SNDCP_MEAN_ACK) { + start_time_ra = sndcp_data->start_time_downlink_ack; + cur_time_ra = sndcp_data->cur_time_downlink_ack; + cur_num_ra = sndcp_data->cur_num_downlink_ack; + cur_pac_ra = sndcp_data->cur_pac_downlink_ack; + } else { + start_time_ra = sndcp_data->start_time_downlink_ack; + cur_time_ra = sndcp_data->cur_time_downlink_ack; + cur_num_ra = sndcp_data->cur_num_downlink_unack; + cur_pac_ra = sndcp_data->cur_pac_downlink_unack; + } + } + + /* + * Increment number of packets. + */ + cur_pac_ra[nsapi] ++; + + + if (start_time_ra[nsapi] == 0) { + vsi_t_time(VSI_CALLER &start_time_ra[nsapi]); + cur_num_ra[nsapi] += len; + } else { + + ULONG mean = 0; + ULONG delta_millis = 0; + + vsi_t_time(VSI_CALLER &cur_time_ra[nsapi]); + cur_num_ra[nsapi] += len; + + delta_millis = cur_time_ra[nsapi] - + start_time_ra[nsapi]; + if (direction == SNDCP_MEAN_UP) { + if (delta_millis > 0) { + mean = (cur_num_ra[nsapi] * 1000) / delta_millis; + TRACE_EVENT_P4( + "nsapi %d up. %d octets in %d ms. %d octets per sec.", + nsapi, + cur_num_ra[nsapi], + delta_millis, + mean + ); + } else { + TRACE_EVENT_P3( + "nsapi %d up. %d octets in %d ms.", + nsapi, + cur_num_ra[nsapi], + delta_millis + ); + } + + } else { /* not (direction == SNDCP_MEAN_UP) */ + if (delta_millis > 0) { + mean = (cur_num_ra[nsapi] * 1000) / delta_millis; + TRACE_EVENT_P4( + "nsapi %d down. %d octets in %d ms. %d octets per sec.", + nsapi, + cur_num_ra[nsapi], + delta_millis, + mean + ); + } else { + TRACE_EVENT_P3( + "nsapi %d down. %d octets in %d ms.", + nsapi, + cur_num_ra[nsapi], + delta_millis + ); + } + } /* not (direction == SNDCP_MEAN_UP) */ + + } + +} + +#endif /* CF_FAST_EXEC */ + + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_reset_xid_block ++------------------------------------------------------------------------------ +| Description : Resets the given T_XID_BLOCK to default values. +| +| Parameters : T_XID_BLOCK* xid_block +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_reset_xid_block (T_XID_BLOCK* xid_block) +{ + TRACE_FUNCTION( "sndcp_reset_xid_block" ); + + /* + * Reset all flags for optional compression field parameters. + */ + xid_block->version_set = FALSE; + xid_block->v42.is_set = FALSE; + xid_block->vj.is_set = FALSE; + + xid_block->v42.nsapis_set = FALSE; + xid_block->v42.p0_set = FALSE; + xid_block->v42.p1_set = FALSE; + xid_block->v42.p2_set = FALSE; + xid_block->vj.nsapis_set = FALSE; + xid_block->vj.s0_m_1_set = FALSE; + /* + * Set fields to default values. + */ + xid_block->v42.nsapis = SNDCP_NSAPIS_DEFAULT; + xid_block->v42.p0 = SNDCP_V42_DEFAULT_DIRECTION; + xid_block->v42.p1 = SNDCP_V42_DEFAULT_P1; + xid_block->v42.p2 = SNDCP_V42_DEFAULT_P2; + + xid_block->vj.nsapis = SNDCP_NSAPIS_DEFAULT; + xid_block->vj.s0_m_1 = SNDCP_VJ_DEFAULT_S0_M_1; + + +} /* sndcp_reset_xid_block() */ + +#endif /* CF_FAST_EXEC */ + +#ifdef _SIMULATION_ +/* ++------------------------------------------------------------------------------ +| Function : sndcp_sdu_to_desc_list ++------------------------------------------------------------------------------ +| Description : copies the given sdu to the given desc_list +| +| Parameters : T_sdu* sdu, +| T_desc_list* desc_list +| ++------------------------------------------------------------------------------ +*/ +#ifdef _SNDCP_DTI_2_ +GLOBAL void sndcp_sdu_to_desc_list(T_sdu* sdu, T_desc_list2* desc_list) { + T_desc2 *desc = NULL; + T_desc2 *last_desc = NULL; +#else /*_SNDCP_DTI_2_*/ +GLOBAL void sndcp_sdu_to_desc_list(T_sdu* sdu, T_desc_list* desc_list) { + T_desc *desc = NULL; + T_desc *last_desc = NULL; +#endif /*_SNDCP_DTI_2_*/ + USHORT sdu_index; + USHORT length; + + + /* + * Begin at the first relevant octet. + */ + sdu_index = sdu->o_buf/8; + + /* + * Initialise descriptor list length. + */ + desc_list->list_len = 0; + + + /* + * Copy complete SDU to descriptor list using descriptors of max. 10 bytes. + */ + while (sdu_index < sdu->l_buf / 8) + { + /* + * Calculate length of descriptor data (= length of remaining sdu buffer + * with a maximum of 10) + */ + length = (sdu_index + 10 < sdu->l_buf / 8) ? + 10 : (sdu->l_buf / 8 - sdu_index); + + /* + * Allocate the necessary size for the data descriptor. The size is + * calculated as follows: + * - take the size of a descriptor structure + * - subtract one because of the array buffer[1] to get the size of + * descriptor control information + * - add number of octets of descriptor data + */ +#ifdef _SNDCP_DTI_2_ + MALLOC (desc, (USHORT)(sizeof(T_desc2) - 1 + length)); +#else /*_SNDCP_DTI_2_*/ + MALLOC (desc, (USHORT)(sizeof(T_desc) - 1 + length)); +#endif /*_SNDCP_DTI_2_*/ + /* + * Fill descriptor control information. + */ + desc->next = (ULONG)NULL; + desc->len = length; +#ifdef _SNDCP_DTI_2_ + desc->offset = 0; + desc->size = desc->len; +#endif + /* + * Add length of descriptor data to list length. + */ + desc_list->list_len += length; + + /* + * Copy user data from SDU to descriptor. + */ + if (length>0) + { + memcpy (desc->buffer, &sdu->buf[sdu_index], length); + } + sdu_index += length; + + if (last_desc) + { + /* + * Add this descriptor (not the first) to the descriptor list. + */ + last_desc->next = (ULONG)desc; + } + else + { + /* + * Insert first descriptor in descriptor list. + */ + desc_list->first = (ULONG)desc; + } + + /* + * Store this descriptor for later use. + */ + last_desc = desc; + } + + } +#endif /* _SIMULATION_ */ + + + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_set_nsapi_ack ++------------------------------------------------------------------------------ +| Description : sets nsapi_ack_ra[nsapi] to ack +| +| Parameters : UBYTE nsapi, BOOL ack +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_set_nsapi_ack(UBYTE nsapi, + BOOL ack) +{ + TRACE_FUNCTION(" sndcp_set_nsapi_ack "); + { + sndcp_data->nsapi_ack_ra[nsapi] = ack; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_set_nsapi_direction ++------------------------------------------------------------------------------ +| Description : sets nsapi_direction_ra[nsapi] to direction +| +| Parameters : UBYTE nsapi, BOOL direction +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_set_nsapi_direction(UBYTE nsapi, + BOOL direction) +{ + TRACE_FUNCTION(" sndcp_set_nsapi_direction "); +#ifdef _SNDCP_DTI_2_ + if (direction == DTI_CHANNEL_TO_LOWER_LAYER) { + sndcp_data->nsapi_direction_ra[nsapi] = DTI_CHANNEL_TO_LOWER_LAYER; + } else { + sndcp_data->nsapi_direction_ra[nsapi] = DTI_CHANNEL_TO_HIGHER_LAYER; +#else /*_SNDCP_DTI_2_*/ + if (direction == SN_HOME) { + sndcp_data->nsapi_direction_ra[nsapi] = HOME; + } else { + sndcp_data->nsapi_direction_ra[nsapi] = NEIGHBOR; +#endif /*_SNDCP_DTI_2_*/ + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_set_nsapi_interface ++------------------------------------------------------------------------------ +| Description : sets nsapi_interface_ra[nsapi] to interfac +| +| Parameters : UBYTE nsapi, U8 interfac +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_set_nsapi_interface(UBYTE nsapi, + U8 interfac) +{ + TRACE_FUNCTION(" sndcp_set_nsapi_interface "); + { + sndcp_data->nsapi_interface_ra[nsapi] = interfac; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_set_nsapi_linkid ++------------------------------------------------------------------------------ +| Description : sets nsapi_linkid_ra[nsapi] to linkid +| +| Parameters : UBYTE nsapi, U32 linkid +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_set_nsapi_linkid(UBYTE nsapi, + U32 linkid) +{ + TRACE_FUNCTION(" sndcp_set_nsapi_linkid "); + { + sndcp_data->nsapi_linkid_ra[nsapi] = linkid; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_set_nsapi_neighbor ++------------------------------------------------------------------------------ +| Description : sets nsapi_neighbor_ra[nsapi] to neighbor +| +| Parameters : UBYTE nsapi, U8* neighbor +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_set_nsapi_neighbor(UBYTE nsapi, + U8* neighbor) +{ + TRACE_FUNCTION(" sndcp_set_nsapi_neighbor "); + { + sndcp_data->nsapi_neighbor_ra[nsapi] = neighbor; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_no_xid ++------------------------------------------------------------------------------ +| Description : XID negotiation during each context (default in our +| implementation) is switched off. +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_no_xid(void) +{ + TRACE_FUNCTION("sndcp_no_xid"); + { + sndcp_data->always_xid = FALSE; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_set_nsapi_prio ++------------------------------------------------------------------------------ +| Description : sets nsapi_prio_ra[nsapi] to prio - 1: +| SNSM prio val is mapped to LL prio val, which is the internal +| representation. +| +| Parameters : UBYTE nsapi, UBYTE prio +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_set_nsapi_prio(UBYTE nsapi, + UBYTE prio) +{ + TRACE_FUNCTION("sndcp_set_nsapi_prio"); + { + sndcp_data->nsapi_prio_ra[nsapi] = prio - 1; + } +} + +#endif /* CF_FAST_EXEC */ + +#ifdef REL99 +/* ++------------------------------------------------------------------------------ +| Function : sndcp_set_nsapi_pktflowid ++------------------------------------------------------------------------------ +| Description : sets pktflowid_ra[nsapi] to packet_flow_identifier: +| SNSM packet flow identifier is mapped to LL pkt_flow_id, which is the internal +| representation. +| +| Parameters : UBYTE nsapi, UBYTE packet_flow_identifier +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_set_nsapi_pktflowid(UBYTE nsapi, + U16 packet_flow_identifier) +{ + TRACE_FUNCTION("sndcp_set_nsapi_pktflowid"); + { + sndcp_data->nsapi_pktflowid_ra[nsapi] = packet_flow_identifier; + } +} +#endif /* CF_FAST_EXEC */ + +#endif /*REL99*/ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_set_nsapi_qos ++------------------------------------------------------------------------------ +| Description : sets nsapi_qos_ra[nsapi] to qos +| +| Parameters : UBYTE nsapi, T_snsm_qos qos +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_set_nsapi_qos(UBYTE nsapi, + T_snsm_qos qos) +{ + TRACE_FUNCTION("sndcp_set_nsapi_qos"); + { + sndcp_data->nsapi_qos_ra[nsapi].delay = qos.delay; + sndcp_data->nsapi_qos_ra[nsapi].relclass = qos.relclass; + sndcp_data->nsapi_qos_ra[nsapi].peak = qos.peak; + sndcp_data->nsapi_qos_ra[nsapi].preced = qos.preced; + sndcp_data->nsapi_qos_ra[nsapi].mean = qos.mean; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_set_nsapi_sapi ++------------------------------------------------------------------------------ +| Description : sets nsapi_sapi_ra[nsapi] to sapi +| +| Parameters : UBYTE nsapi, UBYTE sapi +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_set_nsapi_sapi(UBYTE nsapi, + UBYTE sapi) +{ + TRACE_FUNCTION("sndcp_set_nsapi_sapi"); + { + sndcp_data->nsapi_sapi_ra[nsapi] = sapi; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_set_nsapi_state ++------------------------------------------------------------------------------ +| Description : adds stat to nsapi_state_ra[nsapi] +| +| Parameters : UBYTE nsapi, UBYTE stat +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC +GLOBAL void sndcp_set_nsapi_state(UBYTE nsapi, + USHORT stat) +{ + TRACE_FUNCTION("sndcp_set_nsapi_state"); + { + sndcp_data->nsapi_state_ra[nsapi] |= stat; + } +} + +#endif /* CF_FAST_EXEC */ + + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_ip_packet_filter ++------------------------------------------------------------------------------ +| Description : The function filters TCP and UDP packets on certain ports +| +| Parameters : T_desc_list2 *desc_list, BOOL *discard +| ++------------------------------------------------------------------------------ +*/ +#ifdef _SNDCP_DTI_2_ +LOCAL void sndcp_ip_packet_filter(T_desc_list2 *desc_list, BOOL *discard) +{ + T_desc2 *desc = (T_desc2 *)desc_list->first; + UBYTE *pack_hdr = &desc->buffer[desc->offset]; + UBYTE *tcp_hdr = NULL, + *udp_hdr = NULL; + USHORT offset = 0; + USHORT src_port = 0; + USHORT dest_port = 0; + + TRACE_FUNCTION("sndcp_ip_packet_filter"); + + if(desc_list == NULL || desc_list->first == NULL || desc_list->list_len == 0){ + *discard = TRUE; /* discard packet */ + return; + } + + offset = (pack_hdr[0] & 0x0f) * 4; /* IP header length in bytes*/ + /* Verify, that the desc has a proper length */ + if(desc->len < (offset + 4)){ + return; + } + + switch(pack_hdr[9]){ + /* ICMP Protocol */ + case 1: + *discard = FALSE; /* don't discard ICMP packets */ + /* TRACE_EVENT("INFO IP FILTER: ICMP packet is sent"); */ + return; + /* TCP Protocol */ + case 6: + tcp_hdr = &pack_hdr[offset]; + src_port |= tcp_hdr[0] << 8; + src_port |= tcp_hdr[1]; + dest_port |= tcp_hdr[2] << 8; + dest_port |= tcp_hdr[3]; + if(src_port == 42 || /* Host Name Server */ + dest_port == 42 || + src_port == 111 || /* Remote Procedure Call */ + dest_port == 111 || + ((src_port > 134) && (src_port < 140)) || /* NetBIOS */ + ((dest_port > 134) && (dest_port < 140)) || /* NetBIOS */ + src_port == 445 || /* Microsoft-DS */ + dest_port == 445 || + src_port == 1025 || /* network blackjack */ + dest_port == 1025 || + src_port == 1196 || /* listener RFS */ + dest_port == 1196 || + src_port == 1433 || /* Microsoft-SQL-Server */ + dest_port == 1433 || + src_port == 1434 || /* Microsoft-SQL-Monitor */ + dest_port == 1434 + ){ + *discard = TRUE; /* discard this TCP packet */ + /*TRACE_EVENT_P2("INFO IP FILTER: TCP packet on dest_port %d, src_port %d is discarded", + dest_port, src_port);*/ + } else { + *discard = FALSE; /* dont't discard this TCP packet */ + /*TRACE_EVENT_P2("INFO IP FILTER: TCP packet on dest_port %d, src_port %d is sent", + dest_port, src_port);*/ + } + return; + /* UDP Protocol */ + case 17: + udp_hdr = &pack_hdr[offset]; + src_port |= udp_hdr[0] << 8; + src_port |= udp_hdr[1]; + dest_port |= udp_hdr[2] << 8; + dest_port |= udp_hdr[3]; + if(src_port == 42 || /* Host Name Server */ + dest_port == 42 || + src_port == 67 || /* DHCP BOOTP Protocol Server */ + dest_port == 67 || + src_port == 68 || /* DHCP BOOTP Protocol Client */ + dest_port == 68 || + src_port == 69 || /* Trivial FTP */ + dest_port == 69 || + src_port == 111 || /* Remote Procedure Call */ + dest_port == 111 || + src_port == 135 || /* NetBIOS & co */ + dest_port == 135 || + src_port == 137 || /* NetBIOS & co*/ + dest_port == 137 || + src_port == 138 || /* NetBIOS & co*/ + dest_port == 138 || + src_port == 139 || /* NetBIOS & co*/ + dest_port == 139 || + src_port == 389 || /* LDAP */ + dest_port == 389 || + src_port == 445 || /* Microsoft-DS */ + dest_port == 445 || + src_port == 1023 || /* network blackjack & co */ + dest_port == 1023 || + src_port == 1026 || /* network blackjack & co */ + dest_port == 1026 || + src_port == 1027 || /* network blackjack & co */ + dest_port == 1027 || + src_port == 1028 || /* network blackjack & co */ + dest_port == 1028 || + src_port == 1029 || /* network blackjack & co */ + dest_port == 1029 + ){ + *discard = TRUE; /* discard this UDP packet */ + /*TRACE_EVENT_P2("INFO IP FILTER: UDP packet on dest_port %d, src_port %d is discarded", + dest_port, src_port);*/ + } else { + *discard = FALSE; /* dont't discard this UDP packet */ + /*TRACE_EVENT_P2("INFO IP FILTER: UDP packet on dest_port %d, src_port %d is sent", + dest_port, src_port);*/ + } + return; + default: + *discard = TRUE; /* discard all other packets */ + TRACE_EVENT_P1("INFO IP FILTER: protocol type %d is discarded", pack_hdr[9]); + return; + } +} +#endif /* _SNDCP_DTI_2_ */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_sig_callback ++------------------------------------------------------------------------------ +| Description : callback function for dti lib. +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +#ifdef _SNDCP_DTI_2_ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_sig_callback(U8 instance, + U8 interfac, + U8 channel, + U8 reason, + T_DTI2_DATA_IND *dti2_data_ind) +{ + T_SN_DATA_REQ* sn_data_req = NULL; + T_SN_UNITDATA_REQ* sn_unitdata_req = NULL; + BOOL ack = FALSE; + + TRACE_FUNCTION("sndcp_sig_callback"); + + + switch(reason) + { + case DTI_REASON_CONNECTION_OPENED: + /* + * set rx and tx state machine of the given interface to idle state + */ + /* + * The nsapi is given here with the parameter 'channel'. + */ + nu_connection_state(channel, TRUE); + break; + case DTI_REASON_CONNECTION_CLOSED: + /* + * set the given interface to closed state + */ + break; + case DTI_REASON_DATA_RECEIVED: + /* + * process received data + */ + /* + * Trace p_id. + */ + + + +#ifdef TI_PS_OP_ICUT_SNDCP + + /* PDP_TBR added SNDCP terminal loopback */ + if ( SNDCP_LOOPBACK == 1) + { + if (bufFull[channel] == FALSE) + { + TRACE_EVENT_P1("LOOPBACK len=%d", dti2_data_ind->desc_list2.list_len); + + dti_send_data(sndcp_data->hDTI, + instance, // U8 instance, + SNDCP_INTERFACE_UNACK, // U8 interface, + channel,// U8 channel, + dti2_data_ind // T_DTI2_DATA_IND *dti_data_ind) + ); + } + else + { + saveDti2_data_ind[channel] = dti2_data_ind; + } + return; + } + + + +#endif /* TI_PS_OP_ICUT_SNDCP */ + + + + + +#ifdef SNDCP_TRACE_ALL + switch (dti2_data_ind->parameters.p_id) { + case DTI_PID_IP: + TRACE_EVENT_P2("dti2_data_ind->parameters.p_id: %02x (%s)", + dti2_data_ind->parameters.p_id, + "DTI_PID_IP"); + break; + case DTI_PID_CTCP: + TRACE_EVENT_P2("dti2_data_ind->parameters.p_id: %02x (%s)", + dti2_data_ind->parameters.p_id, + "DTI_PID_CTCP"); + break; + case DTI_PID_UTCP: + TRACE_EVENT_P2("dti2_data_ind->parameters.p_id: %02x (%s)", + dti2_data_ind->parameters.p_id, + "DTI_PID_UTCP"); + break; + case DTI_PID_UOS: + TRACE_EVENT_P2("dti2_data_ind->parameters.p_id: %02x (%s)", + dti2_data_ind->parameters.p_id, + "DTI_PID_UOS"); + break; + default: + TRACE_EVENT_P2("dti2_data_ind->parameters.p_id: %02x (%s)", + dti2_data_ind->parameters.p_id, + "unknown"); + + + } +#endif /* SNDCP_TRACE_ALL */ + /* + * Discard DTI primitive if the config prim "DISCARD" was received + */ + sndcp_data->nu = &sndcp_data->nu_base[channel]; + if(sndcp_data->nu->discard){ + TRACE_EVENT_P1("INFO DISCARD: UL packet with length %d is discarded", + dti2_data_ind->desc_list2.list_len ); + sndcp_data->nu->discarded_data += dti2_data_ind->desc_list2.list_len; + PFREE_DESC2(dti2_data_ind); + dti2_data_ind = NULL; + break; + } + /* + * If the IP filter is enabled (config prim "IP_FILTER_ON" was received), + * filter the packets. + */ + if(sndcp_data->ip_filter){ + BOOL discard; + /* Statistics Trace */ + TRACE_EVENT_P3("INFO NSAPI[%d]: sent bytes: %d, discarded bytes: %d", + channel, sndcp_data->nu->sent_data, sndcp_data->nu->discarded_data); + sndcp_ip_packet_filter(&dti2_data_ind->desc_list2, &discard); + if(discard){ + sndcp_data->nu->discarded_data += dti2_data_ind->desc_list2.list_len; + PFREE_DESC2(dti2_data_ind); + dti2_data_ind = NULL; + break; + } else { + sndcp_data->nu->sent_data += dti2_data_ind->desc_list2.list_len; + } + } + /* + * Copy dti_data_ind to sn_[unit]data_ind and enter nu service the + * old way. + */ + sndcp_get_nsapi_ack(channel, &ack); + if (ack) { + /* + * Allocate a "normal" SN_DATA_REQ primitive and copy the data + * of the test primitive to that one + */ + MALLOC(sn_data_req, sizeof(T_SN_DATA_REQ)); + sn_data_req->nsapi = channel; + sn_data_req->p_id = dti2_data_ind->parameters.p_id; + sn_data_req->desc_list2 = dti2_data_ind->desc_list2; + + /* + * Free the received dti primitive. + */ + PFREE (dti2_data_ind); + dti2_data_ind = NULL; + + nu_sn_data_req(sn_data_req); + + } else { + /* + * Allocate a "normal" SN_UNITDATA_REQ primitive and copy the data + * of the test primitive to that one + */ + MALLOC(sn_unitdata_req, sizeof(T_SN_UNITDATA_REQ)); + + sn_unitdata_req->nsapi = channel; + sn_unitdata_req->p_id = dti2_data_ind->parameters.p_id; + sn_unitdata_req->desc_list2 = dti2_data_ind->desc_list2; + + /* + * Free the received dti 2 primitive. + */ + PFREE (dti2_data_ind); + dti2_data_ind = NULL; + + nu_sn_unitdata_req(sn_unitdata_req); + + } + + break; + case DTI_REASON_TX_BUFFER_FULL: + /* + * set tx state machine of the given interface to TX_IDLE state + */ + + + +#ifdef TI_PS_OP_ICUT_SNDCP + + /* PDP_TBR added SNDCP terminal loopback */ + if (SNDCP_LOOPBACK == 1) + { + dti_stop(sndcp_data->hDTI, + instance, + interfac, + channel); + bufFull[channel] = TRUE; + TRACE_EVENT("SNDCP BUFFER IS FULL"); + } + +#endif /* TI_PS_OP_ICUT_SNDCP */ + + + + /* + * Will be ignored. + */ + break; + case DTI_REASON_TX_BUFFER_READY: + /* + * set tx state machine of the given interface to TX_READY state + */ + + + + +#ifdef TI_PS_OP_ICUT_SNDCP + /* PDP_TBR added SNDCP terminal loopback */ + if ( SNDCP_LOOPBACK == 1) + { + dti_start(sndcp_data->hDTI, + instance, + interfac, + channel); + bufFull[channel] = FALSE; + TRACE_ERROR("SNDCP BUFFER IS READY"); + if (saveDti2_data_ind[channel] != NULL) + { + TRACE_EVENT_P1("LOOPBACK len=%d", dti2_data_ind->desc_list2.list_len); + + dti_send_data(sndcp_data->hDTI, + instance, // U8 instance, + SNDCP_INTERFACE_UNACK, // U8 interface, + channel,// U8 channel, + saveDti2_data_ind[channel] // T_DTI2_DATA_IND *dti_data_ind) + ); + saveDti2_data_ind[channel] = NULL; + + } + break; + } +#endif /* TI_PS_OP_ICUT_SNDCP */ + + + + + /* + * Reaction will be like reaction to SN_GET[UNIT]DATA_REQ. + */ + nd_dti_buffer_ready(channel); + break; + default: + TRACE_ERROR("sndcp_sig_callback called with undefined reason"); + } +} + +#endif /* CF_FAST_EXEC */ + + +#else /*_SNDCP_DTI_2_*/ + +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_sig_callback(U8 instance, + U8 interfac, + U8 channel, + U8 reason, + T_DTI_DATA_IND *dti_data_ind) +{ + TRACE_FUNCTION("sndcp_sig_callback"); + + switch(reason) + { + case DTI_REASON_CONNECTION_OPENED: + /* + * set rx and tx state machine of the given interface to idle state + */ + /* + * The nsapi is given here with the parameter 'channel'. + */ + nu_connection_state(channel, TRUE); + break; + case DTI_REASON_CONNECTION_CLOSED: + /* + * set the given interface to closed state + */ + break; + case DTI_REASON_DATA_RECEIVED: + /* + * process received data + */ + /* + * Trace p_id. + */ +#ifdef SNDCP_TRACE_ALL + switch (dti_data_ind->p_id) { + case DTI_PID_IP: + TRACE_EVENT_P2("dti_data_ind->p_id: %02x (%s)", + dti_data_ind->p_id, + "DTI_PID_IP"); + break; + case DTI_PID_CTCP: + TRACE_EVENT_P2("dti_data_ind->p_id: %02x (%s)", + dti_data_ind->p_id, + "DTI_PID_CTCP"); + break; + case DTI_PID_UTCP: + TRACE_EVENT_P2("dti_data_ind->p_id: %02x (%s)", + dti_data_ind->p_id, + "DTI_PID_UTCP"); + break; + case DTI_PID_FRAME: + TRACE_EVENT_P2("dti_data_ind->p_id: %02x (%s)", + dti_data_ind->p_id, + "DTI_PID_FRAME"); + break; + default: + TRACE_EVENT_P2("dti_data_ind->p_id: %02x (%s)", + dti_data_ind->p_id, + "unknown"); + + + } +#endif /* SNDCP_TRACE_ALL */ + /* + * Copy dti_data_ind to sn_[unit]data_ind and enter nu service the + * old way. + */ + if (interfac == SNDCP_INTERFACE_ACK) { + /* + * Allocate a "normal" SN_DATA_REQ primitive and copy the data + * of the test primitive to that one + */ + PALLOC_DESC (sn_data_req, SN_DATA_REQ); + + sn_data_req->nsapi = channel; + sn_data_req->p_id = dti_data_ind->p_id; + sn_data_req->desc_list = dti_data_ind->desc_list; + + /* + * Free the received dti primitive. + */ + PFREE (dti_data_ind); + dti_data_ind = NULL; + + nu_sn_data_req(sn_data_req); + + } else { + /* + * Allocate a "normal" SN_UNITDATA_REQ primitive and copy the data + * of the test primitive to that one + */ + PALLOC_DESC (sn_unitdata_req, SN_UNITDATA_REQ); + + sn_unitdata_req->nsapi = channel; + sn_unitdata_req->p_id = dti_data_ind->p_id; + sn_unitdata_req->desc_list = dti_data_ind->desc_list; + + /* + * Free the received test primitive. + */ + PFREE (dti_data_ind); + dti_data_ind = NULL; + + nu_sn_unitdata_req(sn_unitdata_req); + + } + + break; + case DTI_REASON_TX_BUFFER_FULL: + /* + * set tx state machine of the given interface to TX_IDLE state + */ + /* + * Will be ignored. + */ + break; + case DTI_REASON_TX_BUFFER_READY: + /* + * set tx state machine of the given interface to TX_READY state + */ + /* + * Reaction will be like reaction to SN_GET[UNIT]DATA_REQ. + */ + nd_dti_buffer_ready(channel); + break; + default: + TRACE_ERROR("sndcp_sig_callback called with undefined reason"); + } +} +#endif /* CF_FAST_EXEC */ + +#endif /*_SNDCP_DTI_2_*/ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_unset_nsapi_state ++------------------------------------------------------------------------------ +| Description : subtracts stat from nsapi_state_ra[nsapi] +| +| Parameters : UBYTE nsapi, UBYTE stat +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_unset_nsapi_state(UBYTE nsapi, + USHORT stat) +{ + TRACE_FUNCTION("sndcp_unset_nsapi_state"); + { + sndcp_data->nsapi_state_ra[nsapi] &= ~ stat; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_set_nsapi_used ++------------------------------------------------------------------------------ +| Description : sets nsapi_used_ra[nsapi] to b +| +| Parameters : UBYTE nsapi, BOOL b +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_set_nsapi_used(UBYTE nsapi, + BOOL b) +{ + TRACE_FUNCTION("sndcp_set_nsapi_used"); + { + sndcp_data->nsapi_used_ra[nsapi] = b; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_set_sapi_ack ++------------------------------------------------------------------------------ +| Description : sets sapi_ack_ra[sapi] to ack +| +| Parameters : UBYTE sapi, BOOL ack +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_set_sapi_ack(UBYTE sapi, + BOOL ack) +{ + TRACE_FUNCTION(" sndcp_set_sapi_ack "); + { + UBYTE sapi_index = 0; + + sndcp_get_sapi_index(sapi, &sapi_index); + sndcp_data->sapi_ack_ra[sapi_index] = ack; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_snsm_qos_to_ll_qos ++------------------------------------------------------------------------------ +| Description : transfers an snsm_qos to an ll_qos +| +| Parameters : T_snsm_qos, T_ll_qos* +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_snsm_qos_to_ll_qos(T_snsm_qos snsm_qos, + T_ll_qos* ll_qos) +{ + TRACE_FUNCTION("sndcp_snsm_qos_to_ll_qos"); + { + ll_qos->delay = snsm_qos.delay; + ll_qos->relclass = snsm_qos.relclass; + ll_qos->peak = snsm_qos.peak; + ll_qos->preced = snsm_qos.preced; + ll_qos->mean = snsm_qos.mean; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_set_sapi_state ++------------------------------------------------------------------------------ +| Description : adds stat to sapi_state_ra[sapi] bitwise +| +| Parameters : UBYTE sapi, UBYTE stat +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_set_sapi_state(UBYTE sapi, + USHORT stat) +{ + TRACE_FUNCTION(" sndcp_set_sapi_state "); + { + UBYTE sapi_index = 0; + sndcp_get_sapi_index(sapi, &sapi_index); + sndcp_data->sapi_state_ra[sapi_index] |= stat; + } +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_unset_sapi_state ++------------------------------------------------------------------------------ +| Description : subtracts stat from sapi_state_ra[sapi] bitwise +| +| Parameters : UBYTE sapi, UBYTE stat +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_unset_sapi_state(UBYTE sapi, + USHORT stat) +{ + TRACE_FUNCTION(" sndcp_unset_sapi_state "); + { + UBYTE sapi_index = 0; + sndcp_get_sapi_index(sapi, &sapi_index); + sndcp_data->sapi_state_ra[sapi_index] &= ~ stat; + } +} + +#endif /* CF_FAST_EXEC */ + +#ifdef FLOW_TRACE +/* ++------------------------------------------------------------------------------ +| Function : sndcp_trace_flow_control ++------------------------------------------------------------------------------ +| Description : traces flow control +| +| Parameters : UBYTE entity, UBYTE uplink, UBYTE sent, BOOL close +| ++------------------------------------------------------------------------------ +*/ +/* + * 0 GRR + * 1 LLC + * 2 SNDCP + * 3 PPP + * 4 UART + */ + +/* +#define FLOW_TRACE_GRR 0 +#define FLOW_TRACE_LLC 1 +#define FLOW_TRACE_SNDCP 2 +#define FLOW_TRACE_PPP 3 +#define FLOW_TRACE_UART 4 + +direction of data transfer + +#define FLOW_TRACE_UP 0 +#define FLOW_TRACE_DOWN 1 + +is sap sitting on top of entity or is lower entity sap used? + +#define FLOW_TRACE_TOP 0 +#define FLOW_TRACE_BOTTOM 1 +*/ + + +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_trace_flow_control(UBYTE entity, UBYTE transfer, UBYTE position, BOOL opened) +{ + TRACE_FUNCTION(" sndcp_trace_flow_control "); +#ifdef SNDCP_TRACE_ALL + TRACE_EVENT_P4("sndcp_trace_flow_control[%d][%d][%d] = %d", + entity, + transfer, + position, + opened); +#endif + { + sndcp_data->flow_control_ra[entity][transfer][position] = opened; + } +} + +#endif /* CF_FAST_EXEC */ + +#endif /* FLOW_TRACE */ + + +#ifdef _SNDCP_DTI_2_ + +#ifdef SNDCP_TRACE_ALL + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_trace_desc_list3_content ++------------------------------------------------------------------------------ +| Description : traces content of a desc3 descriptor list +| +| Parameters : desc_list3 descriptor list +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_trace_desc_list3_content(T_desc_list3 desc_list3) +{ + U16 current_pos = 0; /* */ + U16 data_len = 0; /* The length of the data to be traced including data offset */ + U8* p_data = NULL; /* Pointer to byte data element */ + T_desc3* p_desc3 = (T_desc3*)desc_list3.first; /* Pointer to the actual desc3 descriptor element */ + + while(p_desc3 != NULL) + { + current_pos = p_desc3->offset; /* In case it is the sndcp header allocation, ENCODE_OFFSET has been considered*/ + p_data = (U8*)p_desc3->buffer; + data_len = current_pos + p_desc3->len; /* p_desc3->len is the total allocation length for sndcp header description */ + while(current_pos <= data_len) + { + TRACE_EVENT_P1 + ("%02x", + p_data[current_pos] + ); + current_pos ++; + } + + p_desc3 = (T_desc3*)p_desc3->next; + } +} + +#endif /* CF_FAST_EXEC */ + +#endif /* SNDCP_TRACE_ALL */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_cl_desc2_attach ++------------------------------------------------------------------------------ +| Description : This function attaches a decriptor list to already allocated +| memory. There is no return value. In case an attempt is made +| to attach to freed or invalid memory, then the FRAME generates +| a trace SYSTEM ERROR. This function does not allocate any new +| memory. +| +| Parameters : T_desc2* pointer to desc2 descriptor. +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +void sndcp_cl_desc2_attach(T_desc2* p_desc2) +{ + + MATTACH(p_desc2); + +} + +#endif /* CF_FAST_EXEC */ +/* ++------------------------------------------------------------------------------ +| Function : sndcp_cl_desc3_free ++------------------------------------------------------------------------------ +| Description : Frees the descriptor connected to the desc3 descriptor. This +| free will when applicable cause the frame to decrease a +| connected counter attached to the allocation or really free +| the memory in case the counter is zero. +| +| Parameters : T_desc3* pointer to desc3 descriptor. +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +void sndcp_cl_desc3_free(T_desc3* p_desc3) +{ + + MFREE(p_desc3->buffer); + p_desc3->buffer = NULL; +} + +#endif /* CF_FAST_EXEC */ + +#endif /* _SNDCP_DTI_2_ */ + + +#ifdef SNDCP_TRACE_ALL + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_trace_sdu ++------------------------------------------------------------------------------ +| Description : traces content of one sdu +| +| Parameters : pointer to sdu +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_trace_sdu(T_sdu* sdu) +{ + + USHORT pos = sdu->o_buf >> 3; + USHORT frame_len = (sdu->l_buf + 7) / 8; + + + TRACE_FUNCTION("sndcp_trace_sdu"); + + while(pos < (frame_len + (sdu->o_buf >> 3))) + { + if (pos + 8 <= (frame_len + (sdu->o_buf >> 3))) { + TRACE_EVENT_P8 + ("%02x %02x %02x %02x %02x %02x %02x %02x", + sdu->buf[pos], + sdu->buf[pos + 1], + sdu->buf[pos + 2], + sdu->buf[pos + 3], + sdu->buf[pos + 4], + sdu->buf[pos + 5], + sdu->buf[pos + 6], + sdu->buf[pos + 7] + ); + pos += 8; + } else if (pos + 7 <= (frame_len + (sdu->o_buf >> 3))){ + TRACE_EVENT_P7 + ("%02x %02x %02x %02x %02x %02x %02x", + sdu->buf[pos], + sdu->buf[pos + 1], + sdu->buf[pos + 2], + sdu->buf[pos + 3], + sdu->buf[pos + 4], + sdu->buf[pos + 5], + sdu->buf[pos + 6] + ); + pos += 7; + } else if (pos + 6 <= (frame_len + (sdu->o_buf >> 3))){ + TRACE_EVENT_P6 + ("%02x %02x %02x %02x %02x %02x", + sdu->buf[pos], + sdu->buf[pos + 1], + sdu->buf[pos + 2], + sdu->buf[pos + 3], + sdu->buf[pos + 4], + sdu->buf[pos + 5] + ); + pos += 6; + } else if (pos + 5 <= (frame_len + (sdu->o_buf >> 3))){ + TRACE_EVENT_P5 + ("%02x %02x %02x %02x %02x", + sdu->buf[pos], + sdu->buf[pos + 1], + sdu->buf[pos + 2], + sdu->buf[pos + 3], + sdu->buf[pos + 4] + ); + pos += 5; + } else if (pos + 4 <= (frame_len + (sdu->o_buf >> 3))){ + TRACE_EVENT_P4 + ("%02x %02x %02x %02x", + sdu->buf[pos], + sdu->buf[pos + 1], + sdu->buf[pos + 2], + sdu->buf[pos + 3] + ); + pos += 4; + } else if (pos + 3 <= (frame_len + (sdu->o_buf >> 3))){ + TRACE_EVENT_P3 + ("%02x %02x %02x", + sdu->buf[pos], + sdu->buf[pos + 1], + sdu->buf[pos + 2] + ); + pos += 3; + } else if (pos + 2 <= (frame_len + (sdu->o_buf >> 3))){ + TRACE_EVENT_P2 + ("%02x %02x", + sdu->buf[pos], + sdu->buf[pos + 1] + ); + pos += 2; + } else if (pos + 1 <= (frame_len + (sdu->o_buf >> 3))){ + TRACE_EVENT_P1 + ("%02x", + sdu->buf[pos] + ); + pos++; + } + + } +} + +#endif /* CF_FAST_EXEC */ + + +#endif /* SNDCP_TRACE_ALL */ + +#ifdef SNDCP_TRACE_BUFFER + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_trace_desc_list ++------------------------------------------------------------------------------ +| Description : traces content of one desc_list +| +| Parameters : pointer to desc_list +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +#ifdef _SNDCP_DTI_2_ +GLOBAL void sndcp_trace_desc_list(T_desc_list2* desc_list) +{ +#else /*_SNDCP_DTI_2_*/ +GLOBAL void sndcp_trace_desc_list(T_desc_list* desc_list) +{ +#endif /*_SNDCP_DTI_2_*/ + USHORT frame_len = desc_list->list_len; +#ifdef _SNDCP_DTI_2_ + T_desc2* desc = (T_desc2*)desc_list->first; + USHORT desc_pos = desc->offset; + USHORT desc_end = desc->len + desc->offset; +#else /*_SNDCP_DTI_2_*/ + T_desc* desc = (T_desc*)desc_list->first; + USHORT desc_pos = 0; + USHORT desc_end = desc->len; +#endif /*_SNDCP_DTI_2_*/ + USHORT list_pos = 0; + + TRACE_FUNCTION("sndcp_trace_desc_list"); + + while(list_pos < frame_len) + { + if (desc != NULL) { + if (desc_pos >= desc_end) { +#ifdef _SNDCP_DTI_2_ + desc = (T_desc2*)desc->next; + desc_pos = desc->offset; + desc_end = desc->len + desc->offset; +#else /*_SNDCP_DTI_2_*/ + desc = (T_desc*)desc->next; + desc_pos = 0; + desc_end = desc->len; +#endif /*_SNDCP_DTI_2_*/ + } + } + if (desc == NULL) { + return; + } + if (desc_pos + 8 <= desc_end) { + TRACE_EVENT_P8 ("%02x %02x %02x %02x %02x %02x %02x %02x ", + desc->buffer[desc_pos], + desc->buffer[desc_pos + 1], + desc->buffer[desc_pos + 2], + desc->buffer[desc_pos + 3], + desc->buffer[desc_pos + 4], + desc->buffer[desc_pos + 5], + desc->buffer[desc_pos + 6], + desc->buffer[desc_pos + 7] + ); + list_pos+= 8; + desc_pos+= 8; + } else if (desc_pos + 7 <= desc_end) { + TRACE_EVENT_P7 ("%02x %02x %02x %02x %02x %02x %02x ", + desc->buffer[desc_pos], + desc->buffer[desc_pos + 1], + desc->buffer[desc_pos + 2], + desc->buffer[desc_pos + 3], + desc->buffer[desc_pos + 4], + desc->buffer[desc_pos + 5], + desc->buffer[desc_pos + 6] + ); + list_pos+= 7; + desc_pos+= 7; + } else if (desc_pos + 6 <= desc_end) { + TRACE_EVENT_P6 ("%02x %02x %02x %02x %02x %02x ", + desc->buffer[desc_pos], + desc->buffer[desc_pos + 1], + desc->buffer[desc_pos + 2], + desc->buffer[desc_pos + 3], + desc->buffer[desc_pos + 4], + desc->buffer[desc_pos + 5] + ); + list_pos+= 6; + desc_pos+= 6; + } else if (desc_pos + 5 <= desc_end) { + TRACE_EVENT_P5 ("%02x %02x %02x %02x %02x ", + desc->buffer[desc_pos], + desc->buffer[desc_pos + 1], + desc->buffer[desc_pos + 2], + desc->buffer[desc_pos + 3], + desc->buffer[desc_pos + 4] + ); + list_pos+= 5; + desc_pos+= 5; + } else if (desc_pos + 4 <= desc_end) { + TRACE_EVENT_P4 ("%02x %02x %02x %02x ", + desc->buffer[desc_pos], + desc->buffer[desc_pos + 1], + desc->buffer[desc_pos + 2], + desc->buffer[desc_pos + 3] + ); + list_pos+= 4; + desc_pos+= 4; + } else if (desc_pos + 3 <= desc_end) { + TRACE_EVENT_P3 ("%02x %02x %02x ", + desc->buffer[desc_pos], + desc->buffer[desc_pos + 1], + desc->buffer[desc_pos + 2] + ); + list_pos+= 3; + desc_pos+= 3; + } else if (desc_pos + 2 <= desc_end) { + TRACE_EVENT_P2 ("%02x %02x ", + desc->buffer[desc_pos], + desc->buffer[desc_pos + 1] + ); + list_pos+= 2; + desc_pos+= 2; + } else if (desc_pos + 1 <= desc_end) { + TRACE_EVENT_P1 ("%02x ", + desc->buffer[desc_pos] + ); + list_pos++; + desc_pos++; + } + + /* break tracing if payload shall not be traced*/ + if(!sndcp_data->trace_ip_datagram && (list_pos >= 40)) + break; + + } /* while(list_pos < frame_len) */ + +} + +#endif /* CF_FAST_EXEC */ + +#endif /* SNDCP_TRACE_BUFFER */ + + + +#ifdef _SNDCP_MEAN_TRACE_ +/* ++------------------------------------------------------------------------------ +| Function : sndcp_sn_count_req ++------------------------------------------------------------------------------ +| Description : reaction to prim SN_COUNT_REQ +| +| Parameters : primitive payload +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void sndcp_sn_count_req(T_SN_COUNT_REQ* sn_count_req) +{ + TRACE_FUNCTION("sndcp_sn_count_req"); + + { + BOOL ack = FALSE; + PALLOC(sn_count_cnf, SN_COUNT_CNF); + + sn_count_cnf->nsapi = sn_count_req->nsapi; + + sndcp_get_nsapi_ack(sn_count_req->nsapi, &ack); + if (ack) { + sn_count_cnf->octets_uplink = + sndcp_data->cur_num_uplink_ack[sn_count_req->nsapi]; + sn_count_cnf->octets_downlink = + sndcp_data->cur_num_downlink_ack[sn_count_req->nsapi]; + + sn_count_cnf->packets_uplink = + sndcp_data->cur_pac_uplink_ack[sn_count_req->nsapi]; + sn_count_cnf->packets_downlink = + sndcp_data->cur_pac_downlink_ack[sn_count_req->nsapi]; + +#ifdef SNDCP_UPM_INCLUDED + if (sn_count_req->reset == NAS_RESET_YES) { +#else + if (sn_count_req->reset == SN_RESET_YES) { +#endif /*SNDCP_UPM_INCLUDED*/ + sndcp_data->cur_num_uplink_ack[sn_count_req->nsapi] = 0; + sndcp_data->cur_num_downlink_ack[sn_count_req->nsapi] = 0; + sndcp_data->cur_pac_uplink_ack[sn_count_req->nsapi] = 0; + sndcp_data->cur_pac_downlink_ack[sn_count_req->nsapi] = 0; + } + + } else { + + sn_count_cnf->octets_uplink = + sndcp_data->cur_num_uplink_unack[sn_count_req->nsapi]; + sn_count_cnf->octets_downlink = + sndcp_data->cur_num_downlink_unack[sn_count_req->nsapi]; + + sn_count_cnf->packets_uplink = + sndcp_data->cur_pac_uplink_unack[sn_count_req->nsapi]; + sn_count_cnf->packets_downlink = + sndcp_data->cur_pac_downlink_unack[sn_count_req->nsapi]; + +#ifdef SNDCP_UPM_INCLUDED + if (sn_count_req->reset == NAS_RESET_YES) { +#else + if (sn_count_req->reset == SN_RESET_YES) { +#endif /*SNDCP_UPM_INCLUDED*/ + sndcp_data->cur_num_uplink_unack[sn_count_req->nsapi] = 0; + sndcp_data->cur_num_downlink_unack[sn_count_req->nsapi] = 0; + sndcp_data->cur_pac_uplink_unack[sn_count_req->nsapi] = 0; + sndcp_data->cur_pac_downlink_unack[sn_count_req->nsapi] = 0; + } + } + +#ifdef SNDCP_UPM_INCLUDED + PSEND(hCommUPM, sn_count_cnf); /*count_cnf goes via UPM*/ +#else + PSEND(hCommMMI, sn_count_cnf); +#endif /*SNDCP_UPM_INCLUDED*/ + + } + + PFREE(sn_count_req); +} + +#endif /* CF_FAST_EXEC */ + +#endif /*_SNDCP_MEAN_TRACE */ + +#ifdef SNDCP_TRACE_IP_DATAGRAM + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_trace_ip_datagram ++------------------------------------------------------------------------------ +| Description : traces content of one desc_list +| +| Parameters : pointer to desc_list +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +#ifdef _SNDCP_DTI_2_ +GLOBAL void sndcp_trace_ip_datagram(T_desc_list2* desc_list) +{ +#else /*_SNDCP_DTI_2_*/ +GLOBAL void sndcp_trace_ip_datagram(T_desc_list* desc_list) +{ +#endif /*_SNDCP_DTI_2_*/ + USHORT frame_len = desc_list->list_len; +#ifdef _SNDCP_DTI_2_ + T_desc2* desc = (T_desc2*)desc_list->first; + USHORT desc_pos = desc->offset; + USHORT desc_end = desc->len + desc->offset; +#else /*_SNDCP_DTI_2_*/ + T_desc* desc = (T_desc*)desc_list->first; + USHORT desc_pos = 0; + USHORT desc_end = desc->len; +#endif /*_SNDCP_DTI_2_*/ + USHORT list_pos = 0; + UBYTE *pack_hdr, *ip_hdr; + USHORT t_length = 0; + USHORT length = 0; + USHORT pid = 0; + USHORT f_offset = 0; + USHORT h_checksum = 0; + USHORT src_port = 0; + USHORT dest_port = 0; + ULONG seq_num = 0; + ULONG ack_num = 0; + USHORT window = 0; + USHORT checksum = 0; + USHORT urg_ptr = 0; + USHORT ip_hlen = 0; /* IP header length */ + USHORT tcp_hlen = 0; /* TCP header length */ + UBYTE tmp_flag = 0; + UBYTE type = 0; + UBYTE code = 0; + /*TRACE_FUNCTION("sndcp_trace_ip_datagram");*/ + + if(!sndcp_data->trace_ip_datagram && !sndcp_data->trace_ip_header){ + return; + } + + while(list_pos < frame_len) + { + if (desc != NULL) { + if (desc_pos >= desc_end) { +#ifdef _SNDCP_DTI_2_ + desc = (T_desc2*)desc->next; + desc_pos = desc->offset; + desc_end = desc->len + desc->offset; +#else /*_SNDCP_DTI_2_*/ + desc = (T_desc*)desc->next; + desc_pos = 0; + desc_end = desc->len; +#endif /*_SNDCP_DTI_2_*/ + if (desc == NULL) { + break; + } + } + } else { + return; + } + if((list_pos == 0) || (list_pos >= t_length)) + { + ip_hdr = &desc->buffer[desc_pos]; + if((ip_hdr[9] != 1) && (ip_hdr[9] != 6) && (ip_hdr[9] != 17)) { + TRACE_EVENT_P1("INFO TRACE: Tracing of protocol type %d not supported", + ip_hdr[9]); + return; + } + + /* Trace IP Header */ + ip_hlen = (ip_hdr[0] & 0x0F) << 2; + if ((desc_pos + ip_hlen) <= desc_end){ + TRACE_EVENT("IP Header"); + TRACE_EVENT_P1(" Protocol Version: %d", + ((ip_hdr[0] & 0xF0) >> 4)); + TRACE_EVENT_P1(" Header Length: %d", (ip_hlen >> 2)); + TRACE_EVENT_P1(" Type Of Service: %d", ip_hdr[1]); + t_length |= ip_hdr[2] << 8; + t_length |= ip_hdr[3]; + TRACE_EVENT_P1(" Total Length: %d", t_length); + pid |= ip_hdr[4] << 8; + pid |= ip_hdr[5]; + TRACE_EVENT_P1(" Packet ID: %d", pid); + TRACE_EVENT_P2(" MF|DF: %d|%d", + (ip_hdr[6] & 0x20) >> 5, + (ip_hdr[6] & 0x40) >> 6); + f_offset |= (ip_hdr[6] & 0x1F) << 8; + f_offset |= ip_hdr[7]; + TRACE_EVENT_P1(" Fragment offset: %d", f_offset); + TRACE_EVENT_P1(" Time To Live: %d", ip_hdr[8]); + if(ip_hdr[9] == 17) { + TRACE_EVENT_P1(" Protocol: UDP(%d)", + ip_hdr[9]); + } else if (ip_hdr[9] == 6) { + TRACE_EVENT_P1(" Protocol: TCP(%d)", + ip_hdr[9]); + } else { + TRACE_EVENT_P1(" Protocol: %d", + ip_hdr[9]); + } + h_checksum |= ip_hdr[10] << 8; + h_checksum |= ip_hdr[11]; + TRACE_EVENT_P1(" Header Checksum: %d", h_checksum); + TRACE_EVENT_P4(" Source Address: %d.%d.%d.%d", + ip_hdr[12], ip_hdr[13], + ip_hdr[14], ip_hdr[15]); + TRACE_EVENT_P4(" Destination Address: %d.%d.%d.%d", + ip_hdr[16], ip_hdr[17], + ip_hdr[18], ip_hdr[19]); + list_pos+= ip_hlen; + desc_pos+= ip_hlen; + } + /* Trace TCP Header */ + if((ip_hdr[9] == 6) && ((desc_pos + 20) <= desc_end)) + { + TRACE_EVENT("TCP Header"); + pack_hdr = &ip_hdr[ip_hlen]; + tcp_hlen = (pack_hdr[12] & 0xF0) >> 2; /* the same as (x>>4)*4 */ + src_port |= pack_hdr[0] << 8; + src_port |= pack_hdr[1]; + TRACE_EVENT_P1(" Source Port: %d", src_port); + dest_port |= pack_hdr[2] << 8; + dest_port |= pack_hdr[3]; + TRACE_EVENT_P1(" Destination Port: %d", dest_port); + seq_num |= pack_hdr[4] << 24; + seq_num |= pack_hdr[5] << 16; + seq_num |= pack_hdr[6] << 8; + seq_num |= pack_hdr[7]; + TRACE_EVENT_P1(" Sequence Number: %u", seq_num); + ack_num |= pack_hdr[8] << 24; + ack_num |= pack_hdr[9] << 16; + ack_num |= pack_hdr[10] << 8; + ack_num |= pack_hdr[11]; + TRACE_EVENT_P1(" Acknowledgment Number: %u", ack_num); + TRACE_EVENT_P1(" Data Offset: %d", (tcp_hlen >> 2)); + TRACE_EVENT_P6(" URG|ACK|PSH|RST|SYN|FIN: %d|%d|%d|%d|%d|%d", + (pack_hdr[13] & 0x20) >> 5, + (pack_hdr[13] & 0x10) >> 4, + (pack_hdr[13] & 0x08) >> 3, + (pack_hdr[13] & 0x04) >> 2, + (pack_hdr[13] & 0x02) >> 1, + (pack_hdr[13] & 0x01) ); + window |= pack_hdr[14] << 8; + window |= pack_hdr[15]; + TRACE_EVENT_P1(" Window Size: %d", window); + checksum |= pack_hdr[16] << 8; + checksum |= pack_hdr[17]; + TRACE_EVENT_P1(" Checksum: %d", checksum); + urg_ptr |= pack_hdr[18] << 8; + urg_ptr |= pack_hdr[19]; + TRACE_EVENT_P1(" Ungent Pointer: 0x%04x", urg_ptr); + list_pos+= tcp_hlen; + desc_pos+= tcp_hlen; + } + /* Trace UDP Header */ + else if((ip_hdr[9] == 17) && ((desc_pos + 8) <= desc_end)) + { + TRACE_EVENT("UDP Header"); + pack_hdr = &ip_hdr[ip_hlen]; + src_port |= pack_hdr[0] << 8; + src_port |= pack_hdr[1]; + TRACE_EVENT_P1(" Source Port: %d", src_port); + dest_port |= pack_hdr[2] << 8; + dest_port |= pack_hdr[3]; + TRACE_EVENT_P1(" Destination Port: %d", dest_port); + length |= pack_hdr[4] << 8; + length |= pack_hdr[5]; + TRACE_EVENT_P1(" Length: %d", length); + checksum |= pack_hdr[6] << 8; + checksum |= pack_hdr[7]; + TRACE_EVENT_P1(" Checksum: %d", checksum); + list_pos+= 8; + desc_pos+= 8; + } + /* Trace ICMP Header */ + else if((ip_hdr[9] == 1) && ((desc_pos + 8) <= desc_end)) + { + TRACE_EVENT("ICMP Header"); + pack_hdr = &ip_hdr[ip_hlen]; + type = pack_hdr[0]; + TRACE_EVENT_P1(" Message Type: %d", type); + code = pack_hdr[1]; + TRACE_EVENT_P1(" Message Code: %d", code); + checksum |= pack_hdr[2] << 8; + checksum |= pack_hdr[3]; + TRACE_EVENT_P1(" Checksum: %d", checksum); + list_pos+= 8; + desc_pos+= 8; + } + }/* if((list_pos == 0) || (list_pos >= t_length)) */ + /* Shall payload be traced? */ + if(!sndcp_data->trace_ip_datagram){ + break; + } + /* Trace Payload */ + if(!tmp_flag && (desc_pos < frame_len)){ + TRACE_EVENT("Payload"); + tmp_flag = 1; + } + /*lint -e661 -e662 possible access/creation of out-of-bounds pointer*/ + if (desc_pos + 16 <= desc_end) { + TRACE_EVENT_P16 (" %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x ", + desc->buffer[desc_pos+0], desc->buffer[desc_pos+1], desc->buffer[desc_pos+2], + desc->buffer[desc_pos+3], desc->buffer[desc_pos+4], desc->buffer[desc_pos+5], + desc->buffer[desc_pos+6], desc->buffer[desc_pos+7], desc->buffer[desc_pos+8], + desc->buffer[desc_pos+9], desc->buffer[desc_pos+10], desc->buffer[desc_pos+11], + desc->buffer[desc_pos+12], desc->buffer[desc_pos+13], desc->buffer[desc_pos+14], + desc->buffer[desc_pos+15]); + list_pos+= 16; + desc_pos+= 16; + } else if (desc_pos + 14 <= desc_end) { + TRACE_EVENT_P14 (" %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + desc->buffer[desc_pos+0], desc->buffer[desc_pos+1], desc->buffer[desc_pos+2], + desc->buffer[desc_pos+3], desc->buffer[desc_pos+4], desc->buffer[desc_pos+5], + desc->buffer[desc_pos+6], desc->buffer[desc_pos+7], desc->buffer[desc_pos+8], + desc->buffer[desc_pos+9], desc->buffer[desc_pos+10], desc->buffer[desc_pos+11], + desc->buffer[desc_pos+12], desc->buffer[desc_pos+13]); + list_pos+= 14; + desc_pos+= 14; + } else if (desc_pos + 12 <= desc_end) { + TRACE_EVENT_P12(" %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x ", + desc->buffer[desc_pos+0], desc->buffer[desc_pos+1], desc->buffer[desc_pos+2], + desc->buffer[desc_pos+3], desc->buffer[desc_pos+4], desc->buffer[desc_pos+5], + desc->buffer[desc_pos+6], desc->buffer[desc_pos+7], desc->buffer[desc_pos+8], + desc->buffer[desc_pos+9], desc->buffer[desc_pos+10], desc->buffer[desc_pos+11]); + list_pos+= 12; + desc_pos+= 12; + } else if (desc_pos + 10 <= desc_end) { + TRACE_EVENT_P10(" %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + desc->buffer[desc_pos+0], desc->buffer[desc_pos+1], desc->buffer[desc_pos+2], + desc->buffer[desc_pos+3], desc->buffer[desc_pos+4], desc->buffer[desc_pos+5], + desc->buffer[desc_pos+6], desc->buffer[desc_pos+7], desc->buffer[desc_pos+8], + desc->buffer[desc_pos+9]); + list_pos+= 10; + desc_pos+= 10; + } else if (desc_pos + 8 <= desc_end) { + TRACE_EVENT_P8 (" %02x %02x %02x %02x %02x %02x %02x %02x ", + desc->buffer[desc_pos+0], desc->buffer[desc_pos+1], desc->buffer[desc_pos+2], + desc->buffer[desc_pos+3], desc->buffer[desc_pos+4], desc->buffer[desc_pos+5], + desc->buffer[desc_pos+6], desc->buffer[desc_pos+7]); + list_pos+= 8; + desc_pos+= 8; + } else if (desc_pos + 7 <= desc_end) { + TRACE_EVENT_P7 (" %02x %02x %02x %02x %02x %02x %02x ", + desc->buffer[desc_pos+0], desc->buffer[desc_pos+1], desc->buffer[desc_pos+2], + desc->buffer[desc_pos+3], desc->buffer[desc_pos+4], desc->buffer[desc_pos+5], + desc->buffer[desc_pos+6]); + list_pos+= 7; + desc_pos+= 7; + } else if (desc_pos + 6 <= desc_end) { + TRACE_EVENT_P6 (" %02x %02x %02x %02x %02x %02x ", + desc->buffer[desc_pos+0], desc->buffer[desc_pos+1], desc->buffer[desc_pos+2], + desc->buffer[desc_pos+3], desc->buffer[desc_pos+4], desc->buffer[desc_pos+5]); + list_pos+= 6; + desc_pos+= 6; + } else if (desc_pos + 5 <= desc_end) { + TRACE_EVENT_P5 (" %02x %02x %02x %02x %02x ", + desc->buffer[desc_pos+0], desc->buffer[desc_pos+1], desc->buffer[desc_pos+2], + desc->buffer[desc_pos+3], desc->buffer[desc_pos+4]); + list_pos+= 5; + desc_pos+= 5; + } else if (desc_pos + 4 <= desc_end) { + TRACE_EVENT_P4 (" %02x %02x %02x %02x ", + desc->buffer[desc_pos+0], desc->buffer[desc_pos+1], + desc->buffer[desc_pos+2], desc->buffer[desc_pos+3]); + list_pos+= 4; + desc_pos+= 4; + } else if (desc_pos + 3 <= desc_end) { + TRACE_EVENT_P3 (" %02x %02x %02x ", + desc->buffer[desc_pos+0], desc->buffer[desc_pos+1], + desc->buffer[desc_pos+2]); + list_pos+= 3; + desc_pos+= 3; + } else if (desc_pos + 2 <= desc_end) { + TRACE_EVENT_P2 (" %02x %02x ", + desc->buffer[desc_pos+0], desc->buffer[desc_pos+1]); + list_pos+= 2; + desc_pos+= 2; + } else if (desc_pos + 1 <= desc_end) { + TRACE_EVENT_P1 (" %02x ", desc->buffer[desc_pos+0]); + list_pos++; + desc_pos++; + } + } /* while(list_pos < frame_len) */ + /*lint -e661 -e662 possible access/creation of out-of-bounds pointer*/ +} +/* ++------------------------------------------------------------------------------ +| Function : sndcp_bin_trace_ip ++------------------------------------------------------------------------------ +| Description : traces content of one desc_list using TRACE_IP macro +| +| Parameters : pointer to desc_list +| direction: SNDCP_UL_PACKET (0x1) +| SNDCP_DL_PACKET (0x2) +| ++------------------------------------------------------------------------------ +*/ +#ifdef _SNDCP_DTI_2_ +GLOBAL void sndcp_bin_trace_ip(T_desc_list2* desc_list, U8 direction) +{ +#else /*_SNDCP_DTI_2_*/ +GLOBAL void sndcp_bin_trace_ip(T_desc_list* desc_list, U8 direction) +{ +#endif /*_SNDCP_DTI_2_*/ + USHORT frame_len = desc_list->list_len; +#ifdef _SNDCP_DTI_2_ + T_desc2* desc = (T_desc2*)desc_list->first; +#else /*_SNDCP_DTI_2_*/ + T_desc* desc = (T_desc*)desc_list->first; +#endif /*_SNDCP_DTI_2_*/ + + U16 pid = 0; + U16 pos = 0; + + TRACE_FUNCTION("sndcp_bin_trace_ip"); + + if(frame_len > 1500){ + TRACE_EVENT("TRACE IP ERROR: IP packet too long."); + return; + } + + while(desc != NULL) + { +#ifdef _SNDCP_DTI_2_ + memcpy(&bin_trace_ip_buf[pos], (U8*)&desc->buffer[desc->offset], desc->len ); + pos += desc->len; + desc = (T_desc2*)desc->next; +#else /*_SNDCP_DTI_2_*/ + memcpy(&bin_trace_ip_buf[pos], (U8*)&desc->buffer[0], desc->len ); + pos += desc->len; + desc = (T_desc*)desc->next; +#endif /*_SNDCP_DTI_2_*/ + } + +#ifdef TRACE_IP + if(direction == SNDCP_DL_PACKET){ + TRACE_IP(SNDCP_handle, SNDCP_handle, DOWNLINK_OPC, \ + (U8*)&bin_trace_ip_buf[0], frame_len); + pid = bin_trace_ip_buf[5] | (bin_trace_ip_buf[4] << 8); + TRACE_EVENT_P1("TRACE IP INFO: Downlink IP Packet, ID: %d", pid); + } else if (direction == SNDCP_UL_PACKET){ + TRACE_IP(SNDCP_handle, SNDCP_handle, UPLINK_OPC, \ + (U8*)&bin_trace_ip_buf[0], frame_len); + pid = bin_trace_ip_buf[5] | (bin_trace_ip_buf[4] << 8); + TRACE_EVENT_P1("TRACE IP INFO: Uplink IP Packet, ID: %d", pid); + } else { + TRACE_EVENT("TRACE IP ERROR: unknown transfer direction."); + } +#else /*TRACE_IP*/ + TRACE_EVENT("SNDCP WARNING: TRACE_IP macro not defined"); +#endif /*TRACE_IP*/ +} + + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_default_ip_trace ++------------------------------------------------------------------------------ +| Description : traces TCP, UDP or ICMP header +| +| Parameters : pointer to desc_list +| direction: SNDCP_UL_PACKET (0x1) +| SNDCP_DL_PACKET (0x2) +| ++------------------------------------------------------------------------------ +*/ +#ifdef _SNDCP_DTI_2_ +GLOBAL void sndcp_default_ip_trace(T_desc_list2 *desc_list, U8 direction) +#else +GLOBAL void sndcp_default_ip_trace(T_desc_list *desc_list, U8 direction) +#endif +{ +#ifdef _SNDCP_DTI_2_ + T_desc2 *desc = (T_desc2 *)desc_list->first; + U8 *ip_hdr = &desc->buffer[desc->offset]; +#else + T_desc *desc = (T_desc *)desc_list->first; + U8 *ip_hdr = &desc->buffer[0]; +#endif + U8 *pk_hdr = NULL; + U16 ip_len = 0; + U16 icmp_seq = 0; + U32 seq_num = 0, + ack_num = 0; + U16 t_length = 0; + U16 pid = 0; + U8 type, code; + U16 win_size = 0; + + TRACE_FUNCTION("sndcp_default_ip_trace"); + + if(desc_list == NULL || desc_list->first == NULL || desc_list->list_len == 0){ + return; + } + + ip_len = (ip_hdr[0] & 0x0f) * 4; /* IP header length in bytes*/ + if(desc->len < ip_len){ + TRACE_EVENT("IP TRACE: can not trace ip header, desc too small"); + return; + } + + pk_hdr = &ip_hdr[ip_len]; /* Pointer to the header on top of IP hdr */ + t_length |= ip_hdr[2] << 8; /* Total packet length */ + t_length |= ip_hdr[3]; + pid |= ip_hdr[4] << 8; /* Unequal packet ID */ + pid |= ip_hdr[5]; + + switch(ip_hdr[9]){ + /* ICMP Protocol */ + case 1: + if(desc->len < (ip_len + 8)){ + TRACE_EVENT("IP TRACE: can not trace icmp header, desc to small"); + return; + } + /* Trace ICMP Header */ + type = pk_hdr[0]; + if(type == 8 || type == 0){ + icmp_seq |= pk_hdr[6]; + icmp_seq |= pk_hdr[7] << 8; + TRACE_EVENT_P4("ICMP Echo: type %d, len %d, pid %d, icmp_seq %d", + type, t_length, pid, icmp_seq); + } else { + code = pk_hdr[1]; + TRACE_EVENT_P5("ICMP Packet: dir %d, len %d, pid %d, type: %d, code: %d", + direction, t_length, pid, type, code); + } + break; + /* TCP Protocol */ + case 6: + if(desc->len < (ip_len + 20)){ + TRACE_EVENT("IP TRACE: can not trace tcp header, desc to small"); + return; + } + seq_num |= pk_hdr[4] << 24; + seq_num |= pk_hdr[5] << 16; + seq_num |= pk_hdr[6] << 8; + seq_num |= pk_hdr[7]; + ack_num |= pk_hdr[8] << 24; + ack_num |= pk_hdr[9] << 16; + ack_num |= pk_hdr[10] << 8; + ack_num |= pk_hdr[11]; + win_size |= pk_hdr[14] << 8; + win_size |= pk_hdr[15]; + + TRACE_EVENT_P14("TCP Packet: dir %d, len %d, pid %d, seq_num %u, ack_num %u, src_ip %d.%d.%d.%d, dst_ip %d.%d.%d.%d, win_size %d", + direction, t_length, pid, seq_num, ack_num, + ip_hdr[12], ip_hdr[13], ip_hdr[14], ip_hdr[15], + ip_hdr[16], ip_hdr[17], ip_hdr[18], ip_hdr[19], win_size); + break; + /* UDP Protocol */ + case 17: + if(desc->len < (ip_len + 8)){ + TRACE_EVENT("IP TRACE: can not trace udp header, desc to small"); + return; + } + TRACE_EVENT_P3("UDP Packet: dir %d, len %d, pid %d", + direction, t_length, pid); + break; + default: + TRACE_EVENT_P1("INFO TRACE: Tracing of protocol type %d not supported", + ip_hdr[9]); + break; + } + + return; +} + +#endif /* CF_FAST_EXEC */ +#endif /* SNDCP_TRACE_IP_DATAGRAM */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_swap2 ++------------------------------------------------------------------------------ +| Description : This routine converts (2 byte) short n from network byte order +| to host byte order. +| +| Parameters : USHORT n +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL USHORT sndcp_swap2(USHORT n) +{ + USHORT tmp = n; + return n = (((tmp & 0xff00) >> 8) | ((tmp & 0x00ff) << 8) ); +} + +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_swap4 ++------------------------------------------------------------------------------ +| Description : This routine converts (4 byte) long n from network byte order +| to host byte order. +| +| Parameters : ULONG n +| ++------------------------------------------------------------------------------ +*/ + +#ifndef CF_FAST_EXEC + +GLOBAL ULONG sndcp_swap4(ULONG n) { + ULONG tmp = n; + return n = ((tmp & 0xff000000) >> 24) | ((tmp & 0x00ff0000) >> 8 ) | + ((tmp & 0x0000ff00) << 8 ) | ((tmp & 0x000000ff) << 24); +} + +#endif /* CF_FAST_EXEC */ +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_nsapi_rec_state ++------------------------------------------------------------------------------ +| Description : The function returns the receiving state for given NSAPI +| +| Parameters : IN : nsapi +| OUT : state +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC +GLOBAL U8 sndcp_get_nsapi_rec_state (U8 nsapi) +{ + TRACE_FUNCTION( "sndcp_get_nsapi_rec_state" ); + + return sndcp_data->rec_states[nsapi]; + +} /* sndcp_get_nsapi_rec_state() */ +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_set_nsapi_rec_state ++------------------------------------------------------------------------------ +| Description : The function sets the receiving state for given NSAPI +| +| Parameters : IN : nsapi +| IN : state +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC +GLOBAL void sndcp_set_nsapi_rec_state (U8 nsapi, U8 state) +{ + TRACE_FUNCTION( "sndcp_set_nsapi_rec_state" ); + + sndcp_data->rec_states[nsapi] = state; + +} /* sndcp_set_nsapi_rec_state() */ +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_npdu_num ++------------------------------------------------------------------------------ +| Description : E X T R A convenience function, not in SDL. +| Gets the N-PDU number from the segment header. +| +| Parameters : ll_unitdata_ind T_LL_UNITDATA_IND*, npdu_num* +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC +LOCAL void sndcp_get_npdu_num (T_LL_UNITDATA_IND* ll_unitdata_ind, USHORT* npdu_num) +{ + USHORT msn_off = 1; + USHORT lsb_off = 2; + UBYTE msn = 0; + UBYTE lsb = 0; + + if ((ll_unitdata_ind->sdu.buf[ll_unitdata_ind->sdu.o_buf / 8]) & 0x40) { + msn_off = 2; + lsb_off = 3; + } + + msn = + ll_unitdata_ind->sdu.buf[(ll_unitdata_ind->sdu.o_buf / 8) + msn_off]; + lsb = + ll_unitdata_ind->sdu.buf[(ll_unitdata_ind->sdu.o_buf / 8) + lsb_off]; + + *npdu_num = ((msn & 0xf) << 8) + lsb; +} /* sndcp_get_npdu_num() */ +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_get_seg_num ++------------------------------------------------------------------------------ +| Description : E X T R A convenience function, not in SDL. +| Gets the NSAPI from the segment header. +| +| Parameters : ll_unitdata_ind T_LL_UNITDATA_IND*, seg_num* +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC +LOCAL void sndcp_get_seg_num (T_LL_UNITDATA_IND* ll_unitdata_ind, UBYTE* seg_num) +{ + *seg_num = (ll_unitdata_ind->sdu.buf[(ll_unitdata_ind->sdu.o_buf / 8) + 2] >> 4); +} /* sd_get_seg_num() */ +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_set_unack_transfer_params ++------------------------------------------------------------------------------ +| Description : There is one N-PDU, whose segments are sent to CIA one by one, +| and that is expected reassembled and decompressed back from CIA. Some +| informations are only given in the first segment. +| This procedure stores the needed elements in service variables that can +| be read before sending a SIG_SD_CIA_TRANSFER_REQ. +| +| Parameters : ll_unitdata_req* +| Pre : Correct instance of sd service must be activated. +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC +GLOBAL void sndcp_set_unack_transfer_params (T_LL_UNITDATA_IND* ll_unitdata_ind) +{ + + UBYTE nsapi = + (ll_unitdata_ind->sdu.buf[(ll_unitdata_ind->sdu.o_buf / 8)]) & 0xf; + + /* + * The dcomp value in the first segment of the currently reassembled N-PDU. + */ + sndcp_data->cur_dcomp[nsapi] = + (ll_unitdata_ind->sdu.buf[ll_unitdata_ind->sdu.o_buf / 8 + 1] & 0xf0) >> 4 ; + /* + * The pcomp value in the first segment of the currently reassembled N-PDU. + */ + sndcp_data->cur_pcomp[nsapi] = + (ll_unitdata_ind->sdu.buf[ll_unitdata_ind->sdu.o_buf / 8 + 1]) & 0xf; + /* + * Reference to N-PDU. + */ + sndcp_data->cur_pdu_ref[nsapi].ref_nsapi = nsapi; + sndcp_get_npdu_num(ll_unitdata_ind, &sndcp_data->cur_pdu_ref[nsapi].ref_npdu_num); + sndcp_get_seg_num(ll_unitdata_ind, &sndcp_data->cur_pdu_ref[nsapi].ref_seg_num); + /* + * First and/or last segment? + */ + sndcp_data->cur_seg_pos[nsapi] = 0; + /* + * if f bit is set + */ + if ((ll_unitdata_ind->sdu.buf[ll_unitdata_ind->sdu.o_buf / 8] & 0x40)) { + sndcp_data->cur_seg_pos[nsapi] += SEG_POS_FIRST; + } + /* + * if m bit is not set + */ + if (!(ll_unitdata_ind->sdu.buf[ll_unitdata_ind->sdu.o_buf / 8] & 0x10)) { + sndcp_data->cur_seg_pos[nsapi] += SEG_POS_LAST; + } +} /* sndcp_set_unack_transfer_params() */ +#endif /* CF_FAST_EXEC */ + +/* ++------------------------------------------------------------------------------ +| Function : sndcp_set_ack_transfer_params ++------------------------------------------------------------------------------ +| Description : There is one N-PDU, whose segments are sent to CIA one by one, +| and that is expected reassembled and decompressed back from CIA. Some +| informations are only given in the first segment. +| This procedure stores the needed elements in service variables that can +| be read before sending a SIG_SDA_CIA_TRANSFER_REQ. +| +| Parameters : ll_data_ind* +| Pre : Correct instance of sda service must be activated. +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC +GLOBAL void sndcp_set_ack_transfer_params (T_LL_DATA_IND* ll_data_ind) +{ + UBYTE nsapi = (ll_data_ind->sdu.buf[(ll_data_ind->sdu.o_buf / 8)]) & 0xf; + + /* + * The dcomp value in the first segment of the currently reassembled N-PDU. + */ + sndcp_data->cur_dcomp[nsapi] = + (ll_data_ind->sdu.buf[ll_data_ind->sdu.o_buf / 8 + 1] & 0xf0) >> 4 ; + /* + * The pcomp value in the first segment of the currently reassembled N-PDU. + */ + sndcp_data->cur_pcomp[nsapi] = + ll_data_ind->sdu.buf[ll_data_ind->sdu.o_buf / 8 + 1] & 0xf; + /* + * Reference to N-PDU. + */ + sndcp_data->cur_pdu_ref[nsapi].ref_nsapi = nsapi; + sndcp_data->cur_pdu_ref[nsapi].ref_npdu_num = + ll_data_ind->sdu.buf[(ll_data_ind->sdu.o_buf >> 3) + 2]; + + + /* + * First and/or last segment? + */ + sndcp_data->cur_seg_pos[nsapi] = 0; + /* + * if f bit is set + */ + if ((ll_data_ind->sdu.buf[ll_data_ind->sdu.o_buf / 8]) & 0x40) { + sndcp_data->cur_seg_pos[nsapi] += SEG_POS_FIRST; + } + /* + * if m bit is not set + */ + if (!((ll_data_ind->sdu.buf[ll_data_ind->sdu.o_buf / 8]) & 0x10)) { + sndcp_data->cur_seg_pos[nsapi] += SEG_POS_LAST; + } +} /* sndcp_set_ack_transfer_params() */ +#endif /* CF_FAST_EXEC */