FreeCalypso > hg > fc-tourmaline
view src/g23m-gprs/sndcp/sndcp_suas.c @ 273:5caa86ee2cfa
enable L1_NEW_AEC in l1_confg.h (bold change)
The AEC function implemented in DSP ROM 3606 on the Calypso silicon
we work with is the one that corresponds to L1_NEW_AEC; the same holds
for DSP 34 and even for DSP 33 with more recent patch versions.
However, TI shipped their TCS211 reference fw with L1_NEW_AEC set to 0,
thus driving AEC the old way if anyone tried to enable it, either via
AT%Nxxxx or via the audio mode facility. As a result, the fw would
try to control features which no longer exist in the DSP (long vs short
echo and the old echo suppression level bits), while providing no way
to tune the 8 new parameter words added to the DSP's NDB page.
The only sensible solution is to bite the bullet and enable L1_NEW_AEC
in L1 config, with fallout propagating into RiViera Audio Service
T_AUDIO_AEC_CFG structure and into /aud/*.cfg binary file format.
The latter fallout will be addressed in further code changes.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 29 Jul 2021 18:32:40 +0000 |
parents | fa8dc04885d8 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : GPRS (8441) | Modul : sndcp_suas.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 : This modul is part of the entity SNDCP and implements all | functions to handles the incoming process internal signals as | described in the SDL-documentation (SUA-statemachine) +----------------------------------------------------------------------------- */ #define ENTITY_SNDCP /*==== INCLUDES =============================================================*/ #include "typedefs.h" /* to get Condat data types */ #include "vsi.h" /* to get a lot of macros */ #include "macdef.h" #include "gsm.h" /* to get a lot of macros */ #include "prim.h" /* to get the definitions of used SAP and directions */ #include <string.h> /* to get memcpy() */ #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_suaf.h" /* to get internal functions of service sua */ #include "sndcp_nus.h" /* to get signal functions to service nu */ #include "sndcp_cias.h" /* to get signal functions to service cia */ /*==== CONST ================================================================*/ /*==== LOCAL VARS ===========================================================*/ /*==== PRIVATE FUNCTIONS ====================================================*/ #ifdef _SNDCP_DTI_2_ /* +------------------------------------------------------------------------------ | Function : sua_add_ll_desc_req_params +------------------------------------------------------------------------------ | Description : sets the parameters of the given ll_desc_req | | Parameters : pdu_ref, ll_desc_req* | +------------------------------------------------------------------------------ */ LOCAL void sua_add_ll_desc_req_params (T_pdu_ref pdu_ref, T_LL_DESC_REQ* ll_desc_req) { T_snsm_qos snsm_qos; /* initialized later with getter */ TRACE_FUNCTION( "sua_add_ll_desc_req_params" ); /* * Set quality of service. */ sndcp_get_nsapi_qos(pdu_ref.ref_nsapi, &snsm_qos); sndcp_snsm_qos_to_ll_qos(snsm_qos, &ll_desc_req->ll_qos); /* * Set radio prio. */ sndcp_get_nsapi_prio(pdu_ref.ref_nsapi, &ll_desc_req->radio_prio); #ifdef REL99 sndcp_get_nsapi_pktflowid(pdu_ref.ref_nsapi, (U16 *)&ll_desc_req->pkt_flow_id); #endif /*REL99*/ /* * Set pdu_ref. */ ll_desc_req->reference1.ref_nsapi = pdu_ref.ref_nsapi; ll_desc_req->reference1.ref_npdu_num = (UBYTE)pdu_ref.ref_npdu_num; ll_desc_req->reference1.ref_seg_num = pdu_ref.ref_seg_num; } /* sua_add_ll_desc_req_params() */ #else /* _SNDCP_DTI_2_ */ /* +------------------------------------------------------------------------------ | Function : sua_add_ll_data_req_params +------------------------------------------------------------------------------ | Description : sets the parameters of the given ll_data_req | | Parameters : pdu_ref, ll_data_req* | +------------------------------------------------------------------------------ */ LOCAL void sua_add_ll_data_req_params (T_pdu_ref pdu_ref, T_LL_DATA_REQ* ll_data_req) { T_snsm_qos snsm_qos; /* initialized later with getter */ TRACE_FUNCTION( "sua_add_ll_data_req_params" ); /* * Set quality of service. */ sndcp_get_nsapi_qos(pdu_ref.ref_nsapi, &snsm_qos); sndcp_snsm_qos_to_ll_qos(snsm_qos, &ll_data_req->ll_qos); /* * Set radio prio. */ sndcp_get_nsapi_prio(pdu_ref.ref_nsapi, &ll_data_req->radio_prio); #ifdef REL99 sndcp_get_nsapi_pktflowid(pdu_ref.ref_nsapi, &ll_data_req->pkt_flow_id); #endif /*REL99*/ /* * Set pdu_ref. */ ll_data_req->reference1.ref_nsapi = pdu_ref.ref_nsapi; ll_data_req->reference1.ref_npdu_num = (UBYTE)pdu_ref.ref_npdu_num; ll_data_req->reference1.ref_seg_num = pdu_ref.ref_seg_num; } /* sua_add_ll_data_req_params() */ #endif /* _SNDCP_DTI_2_ */ #ifdef _SNDCP_DTI_2_ /* +------------------------------------------------------------------------------ | Function : sua_add_sn_header +------------------------------------------------------------------------------ | Description : sets the segment header in the given ll_desc_req | | Parameters : first and/or last segment , ll_desc_req*, packet type. | +------------------------------------------------------------------------------ */ LOCAL void sua_add_sn_header (U8 seg_pos, T_pdu_ref pdu_ref, T_LL_DESC_REQ* ll_desc_req, U8 packet_type) { USHORT offset = ENCODE_OFFSET_BYTE; BOOL compressed = FALSE; T_desc3* desc3 = NULL; U8* sndcp_header = NULL; U8 sapi_index = 0; TRACE_FUNCTION( "sua_add_sn_header" ); /* Get the descriptor describing the memory area with the sndcp header */ desc3 = (T_desc3*)ll_desc_req->desc_list3.first; sndcp_header = (U8*)desc3->buffer; sndcp_header[offset] = 0; sndcp_get_sapi_index(ll_desc_req->sapi, &sapi_index); /* * Octet 1, F bit. */ if ((seg_pos & SEG_POS_FIRST) > 0) { sndcp_header[offset] += (1 << 6); } /* * Octet 1, 0 for SN_DATA, i.e. nothing. */ /* * Octet 1, M bit. */ if ((seg_pos & SEG_POS_LAST) == 0) { sndcp_header[offset] += (1 << 4); } /* * Octet 1, NSAPI number. */ sndcp_header[offset] += pdu_ref.ref_nsapi; offset ++; if ((seg_pos & SEG_POS_FIRST) > 0) { sndcp_header[offset] = 0; /* * This is the first bit. * Find d/pcomp values and set them. */ /* * Octet 2, dcomp */ sndcp_header[offset] += (U8)(sndcp_data->mg.cur_xid_block[sapi_index].v42.dcomp << 4); /* * Octet 2, pcomp */ sndcp_is_nsapi_header_compressed(pdu_ref.ref_nsapi, &compressed); if (compressed) { if (packet_type == TYPE_UNCOMPRESSED_TCP) { /* * Uncompressed TCP. */ sndcp_header[offset] = sndcp_data->mg.cur_xid_block[sapi_index].vj.pcomp1; } else if (packet_type == TYPE_IP) { /* * IP. */ sndcp_header[offset] = 0; } else { /* * Compressed TCP. */ sndcp_header[offset] = sndcp_data->mg.cur_xid_block[sapi_index].vj.pcomp2; } } offset ++; } /* * Octet 3, N-PDU number, if F bit set to 1. */ if ((seg_pos & SEG_POS_FIRST) > 0) { sndcp_header[offset] = (U8)pdu_ref.ref_npdu_num; } } /* sua_add_sn_header() */ #else /* _SNDCP_DTI_2_ */ /* +------------------------------------------------------------------------------ | Function : sua_add_sn_header +------------------------------------------------------------------------------ | Description : sets the segment header in the given ll_data_req | | Parameters : first and/or last segment , ll_data_req*, packet type. | +------------------------------------------------------------------------------ */ LOCAL void sua_add_sn_header (UBYTE seg_pos, T_pdu_ref pdu_ref, T_LL_DATA_REQ* ll_data_req, UBYTE packet_type) { USHORT offset = ll_data_req->sdu.o_buf / 8; BOOL compressed = FALSE; TRACE_FUNCTION( "sua_add_sn_header" ); ll_data_req->sdu.buf[offset] = 0; /* * Octet 1, F bit. */ if ((seg_pos & SEG_POS_FIRST) > 0) { ll_data_req->sdu.buf[offset] += (1 << 6); } /* * Octet 1, 0 for SN_DATA, i.e. nothing. */ /* * Octet 1, M bit. */ if ((seg_pos & SEG_POS_LAST) == 0) { ll_data_req->sdu.buf[offset] += (1 << 4); } /* * Octet 1, NSAPI number. */ ll_data_req->sdu.buf[offset] += pdu_ref.ref_nsapi; offset ++; if ((seg_pos & SEG_POS_FIRST) > 0) { ll_data_req->sdu.buf[offset] = 0; /* * This is the first bit. * Find d/pcomp values and set them. */ /* * Octet 2, dcomp */ ll_data_req->sdu.buf[offset] += (UBYTE)(sndcp_data->su->cur_xid_block.v42.dcomp << 4); /* * Octet 2, pcomp */ sndcp_is_nsapi_header_compressed(pdu_ref.ref_nsapi, &compressed); if (compressed) { if (packet_type == TYPE_UNCOMPRESSED_TCP) { /* * Uncompressed TCP. */ ll_data_req->sdu.buf[offset] = sndcp_data->sua->cur_xid_block.vj.pcomp1; } else if (packet_type == TYPE_IP) { /* * IP. */ ll_data_req->sdu.buf[offset] = 0; } else { /* * Compressed TCP. */ ll_data_req->sdu.buf[offset] = sndcp_data->sua->cur_xid_block.vj.pcomp2; } } offset ++; } /* * Octet 3, N-PDU number, if F bit set to 1. */ if ((seg_pos & SEG_POS_FIRST) > 0) { ll_data_req->sdu.buf[offset] = (UBYTE)pdu_ref.ref_npdu_num; } } /* sua_add_sn_header() */ #endif /* _SNDCP_DTI_2_ */ /*==== PUBLIC FUNCTIONS =====================================================*/ #ifdef _SNDCP_DTI_2_ /* +------------------------------------------------------------------------------ | Function : sig_cia_sua_cia_comp_ind +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_CIA_SUA_CIA_COMP_IND | | Parameters : cia_comp_ind* | +------------------------------------------------------------------------------ */ GLOBAL void sig_cia_sua_cia_comp_ind (T_CIA_COMP_IND* cia_comp_ind) { U8 sapi_index = 0; TRACE_ISIG( "sig_cia_cia_sua_comp_ind" ); /* * Set service instance according to sapi in signal. */ sndcp_get_sapi_index(cia_comp_ind->sapi, &sapi_index); sndcp_data->sua = & sndcp_data->sua_base[sapi_index]; /* * Mark segment as transmitted for later acknowledgement. */ sua_mark_segment((U8)cia_comp_ind->pdu_ref.ref_npdu_num, cia_comp_ind->pdu_ref.ref_nsapi); switch( GET_STATE( SUA ) ) { case SUA_LLC_RECEPTIVE_SUSPEND: case SUA_LLC_NOT_RECEPTIVE: case SUA_LLC_NOT_RECEPTIVE_SUSPEND: { /* * Save seg_pos and pdu_ref from cia_comp_ind. */ U8 seg_pos = cia_comp_ind->seg_pos; T_pdu_ref pdu_ref = cia_comp_ind->pdu_ref; PALLOC(ll_desc_req, LL_DESC_REQ); ll_desc_req->sapi = cia_comp_ind->sapi; ll_desc_req->tlli = cia_comp_ind->tlli; /* Single parameter copy qos needed due to different SAPs */ ll_desc_req->ll_qos.delay = cia_comp_ind->cia_qos.delay; ll_desc_req->ll_qos.relclass = cia_comp_ind->cia_qos.relclass; ll_desc_req->ll_qos.peak = cia_comp_ind->cia_qos.peak; ll_desc_req->ll_qos.preced = cia_comp_ind->cia_qos.preced; ll_desc_req->ll_qos.mean = cia_comp_ind->cia_qos.mean; /* radio_prio not defined, handled in separate function later */ ll_desc_req->reserved_data_req1 = cia_comp_ind->comp_inst; ll_desc_req->reference1.ref_nsapi = cia_comp_ind->pdu_ref.ref_nsapi; ll_desc_req->reference1.ref_npdu_num = cia_comp_ind->pdu_ref.ref_npdu_num; ll_desc_req->reference1.ref_seg_num = cia_comp_ind->pdu_ref.ref_seg_num; ll_desc_req->seg_pos = cia_comp_ind->seg_pos; /* attached_counter not copied */ /* cipher not copied */ ll_desc_req->desc_list3.list_len = cia_comp_ind->desc_list3.list_len; ll_desc_req->desc_list3.first = cia_comp_ind->desc_list3.first; sua_add_ll_desc_req_params(cia_comp_ind->pdu_ref, ll_desc_req); sua_add_sn_header(seg_pos, pdu_ref, ll_desc_req, cia_comp_ind->packet_type); /* All information has been transferred remove the compression primitive */ MFREE(cia_comp_ind); /* * Write the ll_desc_req prim to ll_desc_q, * increment write pointer. */ sndcp_data->sua->ll_desc_q[sndcp_data->sua->ll_desc_q_write] = ll_desc_req; sndcp_data->sua->ll_desc_q_write = (sndcp_data->sua->ll_desc_q_write + 1) % SNDCP_SEGMENT_NUMBERS_ACK; } break; case SUA_LLC_RECEPTIVE: { /* * Save seg_pos and pdu_ref from cia_comp_ind. */ U8 ll_desc_seg_pos; U8 ll_desc_nsapi; U8 ll_desc_sapi; U8 seg_pos = cia_comp_ind->seg_pos; T_pdu_ref pdu_ref = cia_comp_ind->pdu_ref; PALLOC(ll_desc_req, LL_DESC_REQ); ll_desc_req->sapi = cia_comp_ind->sapi; ll_desc_req->tlli = cia_comp_ind->tlli; ll_desc_req->ll_qos.delay = cia_comp_ind->cia_qos.delay; ll_desc_req->ll_qos.relclass = cia_comp_ind->cia_qos.relclass; ll_desc_req->ll_qos.peak = cia_comp_ind->cia_qos.peak; ll_desc_req->ll_qos.preced = cia_comp_ind->cia_qos.preced; ll_desc_req->ll_qos.mean = cia_comp_ind->cia_qos.mean; /* radio_prio not defined, handled in separate function later */ ll_desc_req->reserved_data_req1 = cia_comp_ind->comp_inst; ll_desc_req->reference1.ref_nsapi = cia_comp_ind->pdu_ref.ref_nsapi; ll_desc_req->reference1.ref_npdu_num = cia_comp_ind->pdu_ref.ref_npdu_num; ll_desc_req->reference1.ref_seg_num = cia_comp_ind->pdu_ref.ref_seg_num; ll_desc_req->seg_pos = cia_comp_ind->seg_pos; /* attached_counter not copied */ /* cipher not copied */ ll_desc_req->desc_list3.list_len = cia_comp_ind->desc_list3.list_len; ll_desc_req->desc_list3.first = cia_comp_ind->desc_list3.first; sua_add_ll_desc_req_params(cia_comp_ind->pdu_ref, ll_desc_req); sua_add_sn_header(seg_pos, pdu_ref, ll_desc_req, cia_comp_ind->packet_type); /* All information has been transferred remove the compression primitive */ MFREE(cia_comp_ind); ll_desc_seg_pos = ll_desc_req->seg_pos; ll_desc_sapi = ll_desc_req->sapi; ll_desc_nsapi = sua_get_nsapi(ll_desc_req); #ifdef _SIMULATION_ #ifndef MULTI_LAYER su_send_ll_data_req_test(ll_desc_req); #else PSEND(hCommLLC, ll_desc_req); #endif /* MULTI_LAYER */ #else /* _SIMULATION_ */ PSEND(hCommLLC, ll_desc_req); #endif /* _SIMULATION_ */ SET_STATE(SUA, SUA_LLC_NOT_RECEPTIVE); if ((ll_desc_seg_pos & SEG_POS_LAST) > 0) { sig_sua_nu_ready_ind( ll_desc_nsapi ); sua_next_sn_data_req( ll_desc_sapi ); sndcp_data->sua->cia_state = CIA_IDLE; } } break; default: TRACE_ERROR( "SIG_CIA_SUA_CIA_COMP_IND unexpected" ); sndcp_cl_desc3_free((T_desc3 *)cia_comp_ind->desc_list3.first); MFREE(cia_comp_ind); break; } } /* sig_cia_sua_cia_comp_ind() */ #else /* _SNDCP_DTI_2_ */ /* +------------------------------------------------------------------------------ | Function : sig_cia_sua_cia_comp_ind +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_CIA_SUA_CIA_COMP_IND | | Parameters : cia_comp_ind* | +------------------------------------------------------------------------------ */ GLOBAL void sig_cia_sua_cia_comp_ind (T_CIA_COMP_IND* cia_comp_ind) { UBYTE sapi_index = 0; TRACE_ISIG( "sig_cia_cia_sua_comp_ind" ); /* * Set service instance according to sapi in signal. */ sndcp_get_sapi_index(cia_comp_ind->sapi, &sapi_index); sndcp_data->sua = & sndcp_data->sua_base[sapi_index]; /* * Mark segment as transmitted for later acknowledgement. */ sua_mark_segment((UBYTE)cia_comp_ind->pdu_ref.ref_npdu_num, cia_comp_ind->pdu_ref.ref_nsapi); switch( GET_STATE( SUA ) ) { case SUA_LLC_RECEPTIVE_SUSPEND: case SUA_LLC_NOT_RECEPTIVE: case SUA_LLC_NOT_RECEPTIVE_SUSPEND: { /* * Save seg_pos and pdu_ref from cia_comp_ind. */ UBYTE seg_pos = cia_comp_ind->seg_pos; T_pdu_ref pdu_ref = cia_comp_ind->pdu_ref; PPASS(cia_comp_ind, ll_data_req, LL_DATA_REQ); sua_add_ll_data_req_params(cia_comp_ind->pdu_ref, ll_data_req); sua_add_sn_header(seg_pos, pdu_ref, ll_data_req, cia_comp_ind->packet_type); /* * Write the ll_data_req prim to ll_data_q, * increment write pointer. */ sndcp_data->sua->ll_data_q[sndcp_data->sua->ll_data_q_write] = ll_data_req; sndcp_data->sua->ll_data_q_write = (sndcp_data->sua->ll_data_q_write + 1) % SNDCP_SEGMENT_NUMBERS_ACK; } break; case SUA_LLC_RECEPTIVE: { /* * Save seg_pos and pdu_ref from cia_comp_ind. */ UBYTE ll_data_seg_pos; UBYTE ll_data_nsapi; UBYTE ll_data_sapi; UBYTE seg_pos = cia_comp_ind->seg_pos; T_pdu_ref pdu_ref = cia_comp_ind->pdu_ref; PPASS(cia_comp_ind, ll_data_req, LL_DATA_REQ); sua_add_ll_data_req_params(cia_comp_ind->pdu_ref, ll_data_req); sua_add_sn_header(seg_pos, pdu_ref, ll_data_req, cia_comp_ind->packet_type); ll_data_seg_pos = ll_data_req->seg_pos; ll_data_sapi = ll_data_req->sapi; ll_data_nsapi = sua_get_nsapi(ll_data_req); PSEND(hCommLLC, ll_data_req); SET_STATE(SUA, SUA_LLC_NOT_RECEPTIVE); if ((ll_data_seg_pos & SEG_POS_LAST) > 0) { sig_sua_nu_ready_ind( ll_data_nsapi ); sua_next_sn_data_req( ll_data_sapi ); sndcp_data->sua->cia_state = CIA_IDLE; } } break; default: TRACE_ERROR( "SIG_CIA_SUA_CIA_COMP_IND unexpected" ); break; } } /* sig_cia_sua_cia_comp_ind() */ #endif /* _SNDCP_DTI_2_ */ /* +------------------------------------------------------------------------------ | Function : sig_mg_sua_delete_pdus +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_MG_SUA_DELETE_PDUS | The same as the one in service su, but everything is in the | acknowledged version here. | cia_state is set to CIA_IDLE. | | Parameters : UBYTE nsapi the affected nsapi, UBYTE sapi the affected sapi, | BOOL destroy defines if data pay load must be freed. | +------------------------------------------------------------------------------ */ GLOBAL void sig_mg_sua_delete_pdus (U8 nsapi, U8 sapi, BOOL destroy) { U8 sapi_index; BOOL ll_q_affected = FALSE; TRACE_ISIG( "sig_mg_sua_delete_pdus" ); /* * Set service instance according to sapi in signal. */ sndcp_get_sapi_index(sapi, &sapi_index); sndcp_data->sua = & sndcp_data->sua_base[sapi_index]; sndcp_data->sua->cia_state = CIA_IDLE; switch( GET_STATE( SUA ) ) { case SUA_LLC_NOT_RECEPTIVE_SUSPEND: case SUA_LLC_RECEPTIVE_SUSPEND: case SUA_LLC_NOT_RECEPTIVE: case SUA_LLC_RECEPTIVE: { /* * Delete affected N-PDUS from sn_data_q. */ BOOL still = TRUE; U8 index = sndcp_data->sua->sn_data_q_read; while (still) { if (index == sndcp_data->sua->sn_data_q_write) { break; } if (sndcp_data->sua->sn_data_q[index]->nsapi == nsapi) { /* * The index for the prims to be shifted when 1 entry is deleted. */ U8 i = 0; if (destroy) { #ifdef _SNDCP_DTI_2_ MFREE_PRIM(sndcp_data->sua->sn_data_q[index]); #else /*_SNDCP_DTI_2_*/ PFREE_DESC(sndcp_data->sua->sn_data_q[index]); #endif /*_SNDCP_DTI_2_*/ } sndcp_data->sua->sn_data_q[index] = NULL; for (i = index; i != sndcp_data->sua->sn_data_q_write; i = (i + 1) % SN_DATA_Q_LEN) { sndcp_data->sua->sn_data_q[i] = sndcp_data->sua->sn_data_q[(i + 1) % SN_DATA_Q_LEN]; sndcp_data->sua->sn_data_q[(i + 1) % SN_DATA_Q_LEN] = NULL; } sndcp_data->sua->sn_data_q_write = (sndcp_data->sua->sn_data_q_write - 1 + SN_DATA_Q_LEN) % SN_DATA_Q_LEN; if (index == sndcp_data->sua->sn_data_q_write) { break; } } else { index = (index + 1) % SN_DATA_Q_LEN; } /* if (sndcp_data->su->sn_unitdata_q[index]->nsapi == nsapi) */ } #ifdef _SNDCP_DTI_2_ /* * Delete affected SN-PDUS from ll_desc_q. */ still = TRUE; index = sndcp_data->sua->ll_desc_q_read; while (still) { if (index == sndcp_data->sua->ll_desc_q_write) { break; } if (sua_get_nsapi(sndcp_data->sua->ll_desc_q[index]) == nsapi) { /* * The index for the prims to be shifted when 1 entry is deleted. */ U8 i = 0; ll_q_affected = TRUE; /* * Free the deleted primitive. */ if (sndcp_data->sua->ll_desc_q[index] != NULL) { T_desc3 *free_help, *help = (T_desc3 *)sndcp_data->sua->ll_desc_q[index]->desc_list3.first; while(help != NULL) { if (destroy) { sndcp_cl_desc3_free(help);/* free help->buffer */ } free_help = help; help = (T_desc3 *)free_help->next; MFREE(free_help); } PFREE(sndcp_data->sua->ll_desc_q[index]); sndcp_data->sua->ll_desc_q[index] = NULL; } for (i = index; i != sndcp_data->sua->ll_desc_q_write; i = (i + 1) % SNDCP_SEGMENT_NUMBERS_ACK) { sndcp_data->sua->ll_desc_q[i] = sndcp_data->sua->ll_desc_q [(i + 1) % SNDCP_SEGMENT_NUMBERS_ACK]; sndcp_data->sua->ll_desc_q [(i + 1) % SNDCP_SEGMENT_NUMBERS_ACK] = NULL; } sndcp_data->sua->ll_desc_q_write = (sndcp_data->sua->ll_desc_q_write - 1 + SNDCP_SEGMENT_NUMBERS_ACK) % SNDCP_SEGMENT_NUMBERS_ACK; if (index == sndcp_data->sua->ll_desc_q_write) { break; } } else { index = (index + 1) % SNDCP_SEGMENT_NUMBERS_ACK; } /* if (sndcp_data->sua->sn_data_q[index]->nsapi == nsapi) { */ } #else /* _SNDCP_DTI_2_ */ /* * Delete affected SN-PDUS from ll_data_q. */ still = TRUE; index = sndcp_data->sua->ll_data_q_read; while (still) { if (index == sndcp_data->sua->ll_data_q_write) { break; } if (sua_get_nsapi(sndcp_data->sua->ll_data_q[index]) == nsapi) { /* * The index for the prims to be shifted when 1 entry is deleted. */ UBYTE i = 0; ll_q_affected = TRUE; /* * Free the deleted primitive. */ if (sndcp_data->sua->ll_data_q[index] != NULL) { PFREE(sndcp_data->sua->ll_data_q[index]); sndcp_data->sua->ll_data_q[index] = NULL; } for (i = index; i != sndcp_data->sua->ll_data_q_write; i = (i + 1) % SNDCP_SEGMENT_NUMBERS_ACK) { sndcp_data->sua->ll_data_q[i] = sndcp_data->sua->ll_data_q [(i + 1) % SNDCP_SEGMENT_NUMBERS_ACK]; sndcp_data->sua->ll_data_q [(i + 1) % SNDCP_SEGMENT_NUMBERS_ACK] = NULL; } sndcp_data->sua->ll_data_q_write = (sndcp_data->sua->ll_data_q_write - 1 + SNDCP_SEGMENT_NUMBERS_ACK) % SNDCP_SEGMENT_NUMBERS_ACK; if (index == sndcp_data->sua->ll_data_q_write) { break; } } else { index = (index + 1) % SNDCP_SEGMENT_NUMBERS_ACK; } /* if (sndcp_data->sua->sn_data_q[index]->nsapi == nsapi) { */ } #endif /* _SNDCP_DTI_2_ */ } /* * if the segments in LL queue were from the affected nsapi then the * next N-PDU is directed to cia. */ if (ll_q_affected) { sua_next_sn_data_req (sapi); } /* * Delete the segment informations. */ { T_SEG_INFO* help = sndcp_data->sua->first_seg_info; while (help != NULL) { T_SEG_INFO* help_next = help->next; if (help->nsapi == nsapi) { if(sndcp_data->sua->first_seg_info == help) sndcp_data->sua->first_seg_info = help_next; MFREE(help); } help = help_next; } } break; default: TRACE_ERROR( "SIG_MG_SUA_DELETE_PDUS unexpected" ); break; } } /* sig_mg_sua_delete_pdus() */ /* +------------------------------------------------------------------------------ | Function : sig_mg_sua_n201 +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_MG_SUA_N201 | | Parameters : UBYTE sapi the affected sapi, USHORT n201 | +------------------------------------------------------------------------------ */ GLOBAL void sig_mg_sua_n201 (UBYTE sapi, USHORT n201) { UBYTE sapi_index = 0; TRACE_ISIG( "sig_mg_sua_n201" ); /* * Set service instance according to sapi in signal. */ sndcp_get_sapi_index(sapi, &sapi_index); sndcp_data->sua = & sndcp_data->sua_base[sapi_index]; switch( GET_STATE( SUA ) ) { case SUA_LLC_NOT_RECEPTIVE_SUSPEND: case SUA_LLC_RECEPTIVE_SUSPEND: case SUA_LLC_NOT_RECEPTIVE: case SUA_LLC_RECEPTIVE: sndcp_data->sua->n201_i = n201; break; default: TRACE_ERROR( "SIG_MG_SUA_N201 unexpected" ); break; } } /* sig_mg_sua_n201() */ /* +------------------------------------------------------------------------------ | Function : sig_mg_sua_reset_ind +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_MG_SUA_RESET_IND | | Parameters : UBYTE sapi the affected sapi | +------------------------------------------------------------------------------ */ GLOBAL void sig_mg_sua_reset_ind (UBYTE sapi) { UBYTE sapi_index = 0; TRACE_ISIG( "sig_mg_sua_reset_ind" ); /* * Set service instance according to sapi in signal. */ sndcp_get_sapi_index(sapi, &sapi_index); sndcp_data->sua = & sndcp_data->sua_base[sapi_index]; switch( GET_STATE( SUA ) ) { case SUA_LLC_NOT_RECEPTIVE_SUSPEND: case SUA_LLC_RECEPTIVE_SUSPEND: case SUA_LLC_NOT_RECEPTIVE: case SUA_LLC_RECEPTIVE: /* * This is only here: */ SET_STATE(SUA, SUA_LLC_NOT_RECEPTIVE); break; default: TRACE_ERROR( "SIG_MG_SUA_RESET_IND unexpected" ); break; } } /* sig_mg_sua_reset_ind() */ #ifdef _SNDCP_DTI_2_ /* +------------------------------------------------------------------------------ | Function : sig_mg_sua_resume +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_MG_SU_RESUME | | Parameters : UBYTE sapi the affected sapi | +------------------------------------------------------------------------------ */ GLOBAL void sig_mg_sua_resume (U8 sapi) { U8 sapi_index = 0; TRACE_ISIG( "sig_mg_sua_resume" ); /* * Set service instance according to sapi in signal. */ sndcp_get_sapi_index(sapi, &sapi_index); sndcp_data->sua = & sndcp_data->sua_base[sapi_index]; switch( GET_STATE( SUA ) ) { case SUA_LLC_NOT_RECEPTIVE_SUSPEND: SET_STATE (SUA, SUA_LLC_NOT_RECEPTIVE); break; case SUA_LLC_RECEPTIVE_SUSPEND: /* * Is queue with LL_DESC_REQ empty? */ if (sndcp_data->sua->ll_desc_q_write == sndcp_data->sua->ll_desc_q_read) { SET_STATE(SUA, SUA_LLC_RECEPTIVE); } else { /* * Get next segment from queue and send it. */ T_LL_DESC_REQ* ll_desc_req = sndcp_data->sua->ll_desc_q[sndcp_data->sua->ll_desc_q_read]; U8 ll_desc_seg_pos = ll_desc_req->seg_pos; U8 ll_desc_nsapi = sua_get_nsapi(ll_desc_req); U8 ll_desc_sapi = ll_desc_req->sapi; sndcp_data->sua->ll_desc_q[sndcp_data->sua->ll_desc_q_read] = NULL; sndcp_data->sua->ll_desc_q_read = (sndcp_data->sua->ll_desc_q_read + 1) % SNDCP_SEGMENT_NUMBERS_ACK; #ifdef _SIMULATION_ su_send_ll_data_req_test(ll_desc_req); #else /* _SIMULATION_ */ PSEND(hCommLLC, ll_desc_req); #endif /* _SIMULATION_ */ SET_STATE(SUA, SUA_LLC_NOT_RECEPTIVE); if ((ll_desc_seg_pos & SEG_POS_LAST) > 0) { sig_sua_nu_ready_ind( ll_desc_nsapi ); sua_next_sn_data_req( ll_desc_sapi ); sndcp_data->sua->cia_state = CIA_IDLE; } } break; case SUA_LLC_NOT_RECEPTIVE: break; case SUA_LLC_RECEPTIVE: break; default: TRACE_ERROR( "SIG_MG_SUA_RESUME unexpected" ); break; } } /* sig_mg_sua_resume() */ #else /* _SNDCP_DTI_2_ */ /* +------------------------------------------------------------------------------ | Function : sig_mg_sua_resume +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_MG_SU_RESUME | | Parameters : UBYTE sapi the affected sapi | +------------------------------------------------------------------------------ */ GLOBAL void sig_mg_sua_resume (UBYTE sapi) { UBYTE sapi_index = 0; TRACE_ISIG( "sig_mg_sua_resume" ); /* * Set service instance according to sapi in signal. */ sndcp_get_sapi_index(sapi, &sapi_index); sndcp_data->sua = & sndcp_data->sua_base[sapi_index]; switch( GET_STATE( SUA ) ) { case SUA_LLC_NOT_RECEPTIVE_SUSPEND: SET_STATE (SUA, SUA_LLC_NOT_RECEPTIVE); break; case SUA_LLC_RECEPTIVE_SUSPEND: /* * Is queue with LL_DATA_REQ empty? */ if (sndcp_data->sua->ll_data_q_write == sndcp_data->sua->ll_data_q_read) { SET_STATE(SUA, SUA_LLC_RECEPTIVE); } else { /* * Get next segment from queue and send it. */ T_LL_DATA_REQ* ll_data_req = sndcp_data->sua->ll_data_q[sndcp_data->sua->ll_data_q_read]; UBYTE ll_data_seg_pos = ll_data_req->seg_pos; UBYTE ll_data_nsapi = sua_get_nsapi(ll_data_req); UBYTE ll_data_sapi = ll_data_req->sapi; sndcp_data->sua->ll_data_q[sndcp_data->sua->ll_data_q_read] = NULL; sndcp_data->sua->ll_data_q_read = (sndcp_data->sua->ll_data_q_read + 1) % SNDCP_SEGMENT_NUMBERS_ACK; PSEND(hCommLLC, ll_data_req); SET_STATE(SUA, SUA_LLC_NOT_RECEPTIVE); if ((ll_data_seg_pos & SEG_POS_LAST) > 0) { sig_sua_nu_ready_ind( ll_data_nsapi ); sua_next_sn_data_req( ll_data_sapi ); sndcp_data->sua->cia_state = CIA_IDLE; } } break; case SUA_LLC_NOT_RECEPTIVE: break; case SUA_LLC_RECEPTIVE: break; default: TRACE_ERROR( "SIG_MG_SUA_RESUME unexpected" ); break; } } /* sig_mg_sua_resume() */ #endif /* _SNDCP_DTI_2_ */ /* +------------------------------------------------------------------------------ | Function : sig_mg_sua_suspend +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_NU_SUA_SUSPEND | | Parameters : SAPI | +------------------------------------------------------------------------------ */ GLOBAL void sig_mg_sua_suspend (UBYTE sapi) { UBYTE sapi_index = 0; TRACE_ISIG( "sig_mg_sua_suspend" ); /* * Set service instance according to sapi in signal. */ sndcp_get_sapi_index(sapi, &sapi_index); sndcp_data->sua = & sndcp_data->sua_base[sapi_index]; switch( GET_STATE( SUA ) ) { case SUA_LLC_NOT_RECEPTIVE_SUSPEND: break; case SUA_LLC_RECEPTIVE_SUSPEND: break; case SUA_LLC_NOT_RECEPTIVE: SET_STATE (SUA, SUA_LLC_NOT_RECEPTIVE_SUSPEND); break; case SUA_LLC_RECEPTIVE: SET_STATE (SUA, SUA_LLC_RECEPTIVE_SUSPEND); break; default: TRACE_ERROR( "SIG_MG_SUA_SUSPEND unexpected" ); break; } } /* sig_mg_sua_suspend() */ /* +------------------------------------------------------------------------------ | Function : sig_nu_sua_data_req +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_NU_SUA_DATA_REQ | | Parameters : SN_DATA_REQ primitive, N-PDU number, NSAPI, SAPI | +------------------------------------------------------------------------------ */ GLOBAL void sig_nu_sua_data_req (T_SN_DATA_REQ* sn_data_req, UBYTE npdu_number, UBYTE nsapi, UBYTE sapi ) { UBYTE sapi_index = 0; TRACE_ISIG( "sig_nu_sua_data_req" ); #ifdef _SNDCP_MEAN_TRACE_ #ifdef _SNDCP_DTI_2_ sndcp_mean_trace(nsapi, SNDCP_MEAN_UP, SNDCP_MEAN_ACK, sn_data_req->desc_list2.list_len); #else /*_SNDCP_DTI_2_*/ sndcp_mean_trace(nsapi, SNDCP_MEAN_UP, SNDCP_MEAN_ACK, sn_data_req->desc_list.list_len); #endif /*_SNDCP_DTI_2_*/ #endif /* _SNDCP_MEAN_TRACE_ */ /* * set service instance according to sapi in signal */ sndcp_get_sapi_index(sapi, &sapi_index); sndcp_data->sua = & sndcp_data->sua_base[sapi_index]; switch( GET_STATE( SUA ) ) { case SUA_LLC_RECEPTIVE_SUSPEND: case SUA_LLC_NOT_RECEPTIVE_SUSPEND: case SUA_LLC_NOT_RECEPTIVE: case SUA_LLC_RECEPTIVE: /* * If queue with NPDUs is empty, and cia is not busy, * send the NPDU to cia, else * add it to the queue. */ if ((sndcp_data->sua->sn_data_q_read == sndcp_data->sua->sn_data_q_write) && (sndcp_data->sua->ll_desc_q_read == sndcp_data->sua->ll_desc_q_write) && sndcp_data->sua->cia_state == CIA_IDLE) { /* * Send the NPDU to cia. */ sndcp_data->sua->cia_state = CIA_BUSY; sig_sua_cia_cia_comp_req(sn_data_req, npdu_number, nsapi, sapi); } else { /* Queue with NPDUs is not empty or cia is busy. */ /* * Write the sn_data_req prim to sn_data_q, * increment write pointer. */ sndcp_data->sua->sn_data_q[sndcp_data->sua->sn_data_q_write] = sn_data_req; sndcp_data->sua->npdu_number_q[sndcp_data->sua->sn_data_q_write] = npdu_number; sndcp_data->sua->sn_data_q_write = (sndcp_data->sua->sn_data_q_write + 1) % SN_DATA_Q_LEN; } /* Queue with NPDUs is not empty or cia is busy. */ break; default: TRACE_ERROR( "SIG_NU_SUA_DATA_REQ unexpected" ); #ifdef _SNDCP_DTI_2_ MFREE_PRIM(sn_data_req); #else /*_SNDCP_DTI_2_*/ PFREE_DESC(sn_data_req); #endif /*_SNDCP_DTI_2_*/ break; } } /* sig_nu_sua_data_req() */ #ifdef _SIMULATION_ #ifdef _SNDCP_DTI_2_ /* +------------------------------------------------------------------------------ | Function : su_send_ll_data_req_test +------------------------------------------------------------------------------ | Description : Only for test purposes. | The given LL_DESC_REQ is copied to an | LL_DATA_REQ and sent for the simulated test environment. | | Parameters : T_LL_DESC_REQ* pointer descriptor data. | +------------------------------------------------------------------------------ */ void su_send_ll_data_req_test(T_LL_DESC_REQ* ll_desc_req) { T_desc3* descriptor = NULL; U8* p_data = NULL; U16 offset = ENCODE_OFFSET_BYTE; PALLOC_SDU(ll_data_req, LL_DATA_REQ, (U16)( ll_desc_req->desc_list3.list_len* 8)); /* * Set parameters in ll_data_req primitive */ ll_data_req->sapi = ll_desc_req->sapi; ll_data_req->tlli = ll_desc_req->tlli; ll_data_req->ll_qos = ll_desc_req->ll_qos; ll_data_req->radio_prio = ll_desc_req->radio_prio; ll_data_req->reserved_data_req1 = ll_desc_req->reserved_data_req1; ll_data_req->reference1 = ll_desc_req->reference1; ll_data_req->seg_pos = ll_desc_req->seg_pos; ll_data_req->attached_counter = ll_desc_req->attached_counter; ll_data_req->reserved_data_req4 = ll_desc_req->reserved_data_req4; #ifdef REL99 ll_data_req->pkt_flow_id = ll_desc_req->pkt_flow_id; #endif /*REL99*/ /* * Set the ENCODE_OFFSET in the uplink sdu to 0, set sdu.l_buf */ ll_data_req->sdu.o_buf = ENCODE_OFFSET; ll_data_req->sdu.l_buf = ll_desc_req->desc_list3.list_len* 8; /* * Copy the data. */ descriptor = (T_desc3*)ll_desc_req->desc_list3.first; while (descriptor != NULL) { T_desc3* help = descriptor; p_data = (U8*)descriptor->buffer; if (descriptor->len>0) { memcpy(&ll_data_req->sdu.buf[offset], &p_data[descriptor->offset], descriptor->len); } offset += descriptor->len; descriptor = (T_desc3*)descriptor->next; sndcp_cl_desc3_free(help); MFREE(help); help = NULL; } PSEND(hCommLLC, ll_data_req); PFREE(ll_desc_req); // MAYBE REMEMBER is this the correct free? } #endif /* _SNDCP_DTI_2_ */ #endif /* _SIMULATION_ */