FCHG: fixed corner case bug of missing discharge init on charger unplug
also turn on LEDC during i2v calibration
line source
+ − /*
+ − +-----------------------------------------------------------------------------
+ − | Project : GPRS (8441)
+ − | Modul : sndcp_sdas.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 (SD-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 "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_sdaf.h" /* to get the internal functions of this service */
+ − #include "sndcp_nds.h" /* to get signals to nd service */
+ −
+ −
+ − /*==== CONST ================================================================*/
+ −
+ − /*==== LOCAL VARS ===========================================================*/
+ −
+ − /*==== PRIVATE FUNCTIONS ====================================================*/
+ −
+ − /*==== PUBLIC FUNCTIONS =====================================================*/
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : sig_cia_sda_cia_decomp_ind
+ − +------------------------------------------------------------------------------
+ − | Description : Handles the internal signal SIG_CIA_SDA_CIA_DECOMP_IND
+ − |
+ − | Parameters : cia_decomp_ind, p_id
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − GLOBAL void sig_cia_sda_cia_decomp_ind (T_CIA_DECOMP_IND* cia_decomp_ind, UBYTE p_id)
+ − {
+ − UBYTE sapi_index = 0;
+ − UBYTE sapi = 0;
+ − UBYTE nsapi= cia_decomp_ind->pdu_ref.ref_nsapi;
+ − BOOL rec = FALSE;
+ − T_SN_DATA_IND* sn_data_ind = NULL;
+ −
+ − TRACE_ISIG( "sig_cia_sda_cia_decomp_ind" );
+ −
+ − /*
+ − * set service instance according to sapi in primitive
+ − */
+ − sndcp_get_nsapi_sapi(cia_decomp_ind->pdu_ref.ref_nsapi, &sapi);
+ − sndcp_get_sapi_index(sapi, &sapi_index);
+ − sndcp_data->sda = & sndcp_data->sda_base[sapi_index];
+ −
+ −
+ − switch( sndcp_get_nsapi_rec_state(nsapi) )
+ − {
+ − case SDA_RECEIVE_FIRST_SEGMENT:
+ − case SDA_RECEIVE_SUBSEQUENT_SEGMENT:
+ − case SDA_ESTABLISH_REQUESTED:
+ − {
+ −
+ − MALLOC(sn_data_ind, sizeof(T_SN_DATA_IND));
+ −
+ − #ifdef _SNDCP_DTI_2_
+ − sn_data_ind->desc_list2.first = cia_decomp_ind->desc_list2.first;
+ − sn_data_ind->desc_list2.list_len = cia_decomp_ind->desc_list2.list_len;
+ − #endif /*_SNDCP_DTI_2_*/
+ −
+ − #ifdef SNDCP_TRACE_ALL
+ −
+ − sndcp_data->cia.cia_decomp_ind_number[nsapi] --;
+ − TRACE_EVENT_P1("number of cia_decomp_ind: % d",
+ − sndcp_data->cia.cia_decomp_ind_number[nsapi]);
+ − #endif /* SNDCP_TRACE_ALL */
+ −
+ − sn_data_ind->nsapi = nsapi;
+ − sn_data_ind->p_id = p_id;
+ − sda_is_nsapi_rec(nsapi, &rec);
+ − if (rec) {
+ − sda_set_nsapi_rec(nsapi, FALSE);
+ − sig_sda_nd_data_ind(nsapi,
+ − sn_data_ind,
+ − (UBYTE)cia_decomp_ind->pdu_ref.ref_npdu_num);
+ − sda_get_data_if_nec(sapi);
+ − } else {
+ − if (sndcp_data->sda->cur_sn_data_ind[nsapi] NEQ NULL)
+ − {
+ − #ifndef NTRACE
+ − #ifdef SNDCP_TRACE_ALL
+ − TRACE_EVENT_P1("Discard cur_sn.. in %s", sndcp_data->sda->state_name);
+ − #endif /* SNDCP_TRACE_ALL */
+ − #endif /* NTRACE */
+ − sda_delete_cur_sn_data_ind(nsapi);
+ − }
+ − sndcp_data->sda->cur_sn_data_ind[nsapi] = sn_data_ind;
+ − sndcp_data->sda->uncomp_npdu_num =
+ − (UBYTE)cia_decomp_ind->pdu_ref.ref_npdu_num;
+ − sndcp_set_nsapi_rec_state(nsapi, SDA_WAIT_NSAPI);
+ − sda_get_data_if_nec ( sapi );
+ − }
+ − }
+ − MFREE(cia_decomp_ind);
+ − break;
+ − default:
+ − TRACE_ERROR( "SIG_CIA_SDA_CIA_DECOMP_IND unexpected" );
+ − MFREE_PRIM(cia_decomp_ind);
+ − break;
+ − }
+ − } /* sig_cia_sda_cia_decomp_ind() */
+ −
+ −
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : sig_mg_sda_delete_npdus
+ − +------------------------------------------------------------------------------
+ − | Description : Handles the internal signal SIG_MG_SD_DELETE_NPDUS
+ − |
+ − | Parameters : affected NSAPI, SAPI
+ − | Pre : If the affected SAPI no longer uses acknowledged LLC operation
+ − | mode, no LL_GETDATA_REQ shall be sent. So sndcp_sapi_state_ra
+ − | must already be set to MG_REL_PENDING before this functon is
+ − | called (if that sub state is desired).
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − GLOBAL void sig_mg_sda_delete_npdus (UBYTE nsapi,
+ − UBYTE sapi)
+ − {
+ − UBYTE sapi_index = 0;
+ −
+ − TRACE_ISIG( "sig_mg_sda_delete_npdus" );
+ −
+ − /*
+ − * set service instance according to sapi in primitive
+ − */
+ − sndcp_get_sapi_index(sapi, &sapi_index);
+ − sndcp_data->sda = & sndcp_data->sda_base[sapi_index];
+ −
+ − switch( sndcp_get_nsapi_rec_state(nsapi) )
+ − {
+ − case SDA_ESTABLISH_REQUESTED:
+ − case SDA_RECEIVE_FIRST_SEGMENT:
+ − case SDA_RECEIVE_SUBSEQUENT_SEGMENT:
+ − if (sndcp_data->sda->cur_sn_data_ind[nsapi] != NULL) {
+ − sda_delete_cur_sn_data_ind(nsapi);
+ − sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT);
+ − } else {
+ − sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT);
+ − }
+ − break;
+ − case SDA_WAIT_NSAPI:
+ − if (sndcp_data->sda->cur_sn_data_ind[nsapi] != NULL) {
+ − USHORT sapi_state = MG_IDLE;
+ −
+ − sda_delete_cur_sn_data_ind(nsapi);
+ − /*
+ − * Does it make sense to request another acknowlegded segment or is
+ − * the whole SAPI now using only unacknowledged mode?
+ − */
+ − sndcp_get_sapi_state(sapi, &sapi_state);
+ − if ((sapi_state & MG_REL) == 0) {
+ − sda_get_data_if_nec(sapi);
+ − }
+ − sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT);
+ − }
+ − break;
+ − default:
+ − TRACE_ERROR( "SIG_MG_SDA_DELETE_NPDUS unexpected" );
+ − break;
+ − }
+ − } /* sig_mg_sda_delete_npdus() */
+ −
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : sig_mg_sda_end_est
+ − +------------------------------------------------------------------------------
+ − | Description : Handles the signal PD_SD_END_EST
+ − |
+ − | Parameters : affected sapi, success
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − GLOBAL void sig_mg_sda_end_est (UBYTE sapi, BOOL success)
+ − {
+ − UBYTE sapi_index = 0;
+ − UBYTE nsapi = 0;
+ −
+ − TRACE_FUNCTION( "sig_pda_sda_est_cnf" );
+ −
+ − /*
+ − * set service instance according to sapi in primitive
+ − */
+ − sndcp_get_sapi_index(sapi, &sapi_index);
+ − sndcp_data->sda = & sndcp_data->sda_base[sapi_index];
+ −
+ − /*
+ − * Send LL_GETDATA_REQ.
+ − */
+ − if (success){
+ − sndcp_data->sda->llc_may_send = FALSE;
+ − sda_get_data_if_nec(sapi);
+ − }
+ − /*
+ − * All nsapis at this sapi that use ack mode, enter
+ − * SDA_ESTABLISH_REQUESTED state.
+ − */
+ − for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi ++) {
+ − UBYTE local_sapi = 0;
+ − BOOL used = FALSE;
+ −
+ − sndcp_is_nsapi_used(nsapi, &used);
+ − if (!used) {
+ − continue;
+ − }
+ − sndcp_get_nsapi_sapi(nsapi, &local_sapi);
+ − if (local_sapi == sapi) {
+ − switch( sndcp_get_nsapi_rec_state(nsapi) )
+ − {
+ − case SDA_ESTABLISH_REQUESTED:
+ − case SDA_RECEIVE_FIRST_SEGMENT:
+ − case SDA_RECEIVE_SUBSEQUENT_SEGMENT:
+ − case SDA_WAIT_NSAPI:
+ − case SDA_ACK_DISCARD:
+ − sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT);
+ − break;
+ − default:
+ − TRACE_EVENT( "SIG_MG_SDA_END_EST unexpected for this NSAPI" );
+ − break;
+ − }
+ − }
+ − } /* for all nsapis */
+ −
+ −
+ − } /* sig_mg_sda_end_est() */
+ −
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : sig_mg_sda_getdata
+ − +------------------------------------------------------------------------------
+ − | Description : Handles the internal signal SIG_MG_SD_GETDATA
+ − |
+ − | Parameters : sapi
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − GLOBAL void sig_mg_sda_getdata (UBYTE sapi, UBYTE nsapi)
+ − {
+ − UBYTE sapi_index = 0;
+ −
+ − TRACE_ISIG( "sig_mg_sda_getdata" );
+ −
+ − /*
+ − * set service instance according to sapi in primitive
+ − */
+ − sndcp_get_sapi_index(sapi, &sapi_index);
+ − sndcp_data->sda = & sndcp_data->sda_base[sapi_index];
+ −
+ − switch( GET_STATE(SDA) )
+ − {
+ − case SDA_DEFAULT:
+ − sda_get_data_if_nec(sapi);
+ − sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT);
+ − break;
+ − default:
+ − TRACE_ERROR( "SIG_MG_SDA_GETDATA unexpected" );
+ − break;
+ − }
+ − } /* sig_mg_sda_getdata() */
+ −
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : sig_cia_sda_getdata
+ − +------------------------------------------------------------------------------
+ − | Description : Handles the internal signal SIG_CIA_SDA_GETDATA
+ − |
+ − | Parameters : sapi
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − GLOBAL void sig_cia_sda_getdata (UBYTE sapi, UBYTE nsapi)
+ − {
+ −
+ − TRACE_ISIG( "sig_cia_sda_getdata" );
+ −
+ − switch( sndcp_get_nsapi_rec_state(nsapi) )
+ − {
+ − case SDA_RECEIVE_FIRST_SEGMENT:
+ − case SDA_RECEIVE_SUBSEQUENT_SEGMENT:
+ − case SDA_WAIT_NSAPI:
+ − sda_get_data_if_nec(sapi);
+ − break;
+ − default:
+ − TRACE_ERROR( "SIG_CIA_SDA_GETDATA unexpected" );
+ − break;
+ − }
+ − } /* sig_cia_sda_getdata() */
+ −
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : sig_nd_sda_getdata_req
+ − +------------------------------------------------------------------------------
+ − | Description : Handles the internal signal SIG_ND_SDA_GETDATA_REQ
+ − |
+ − | Parameters : affected sapi, affected nsapi
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − GLOBAL void sig_nd_sda_getdata_req (UBYTE sapi,
+ − UBYTE nsapi)
+ − {
+ − UBYTE sapi_index = 0;
+ −
+ − TRACE_ISIG( "sig_nd_sda_getdata_req" );
+ −
+ − /*
+ − * set service instance according to sapi in primitive
+ − */
+ − sndcp_get_sapi_index(sapi, &sapi_index);
+ − sndcp_data->sda = & sndcp_data->sda_base[sapi_index];
+ −
+ − switch( sndcp_get_nsapi_rec_state(nsapi) )
+ − {
+ − case SDA_RECEIVE_FIRST_SEGMENT:
+ − case SDA_RECEIVE_SUBSEQUENT_SEGMENT:
+ − sda_set_nsapi_rec(nsapi, TRUE);
+ − break;
+ − case SDA_WAIT_NSAPI:
+ − if (sndcp_data->sda->cur_sn_data_ind[nsapi] != NULL) {
+ − /*
+ − * Send the just reassembled N-PDU (must be present because of state!).
+ − */
+ − sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT);
+ − sig_sda_nd_data_ind(nsapi,
+ − sndcp_data->sda->cur_sn_data_ind[nsapi],
+ − sndcp_data->sda->uncomp_npdu_num);
+ − sndcp_data->sda->cur_sn_data_ind[nsapi] = NULL;
+ − sda_get_data_if_nec(sapi);
+ − } else {
+ − /*
+ − * Set the receptive for the given nsapi.
+ − */
+ − sda_set_nsapi_rec(nsapi, TRUE);
+ − }
+ − break;
+ − default:
+ − TRACE_ERROR( "SIG_ND_SDA_GETDATA_REQ unexpected" );
+ − break;
+ − }
+ − } /* sig_nd_sda_getdata_req() */
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : sig_mg_sda_start_est
+ − +------------------------------------------------------------------------------
+ − | Description : Handles the signal PD_SD_START_EST
+ − |
+ − | Parameters : affected sapi
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − GLOBAL void sig_mg_sda_start_est (UBYTE sapi)
+ − {
+ − UBYTE nsapi = 0;
+ −
+ − TRACE_FUNCTION( "sig_pda_sda_start_est" );
+ −
+ − /*
+ − * All nsapis at this sapi that use ack mode, enter
+ − * SDA_ESTABLISH_REQUESTED state.
+ − */
+ − for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi ++) {
+ − UBYTE sapi_help = 0;
+ − BOOL used = FALSE;
+ −
+ − sndcp_is_nsapi_used(nsapi, &used);
+ − if (!used) {
+ − continue;
+ − }
+ − sndcp_get_nsapi_sapi(nsapi, &sapi_help);
+ − if (sapi_help == sapi) {
+ − switch( sndcp_get_nsapi_rec_state(nsapi) )
+ − {
+ − case SDA_ESTABLISH_REQUESTED:
+ − case SDA_RECEIVE_FIRST_SEGMENT:
+ − case SDA_RECEIVE_SUBSEQUENT_SEGMENT:
+ − case SDA_WAIT_NSAPI:
+ − sndcp_set_nsapi_rec_state(nsapi, SDA_ESTABLISH_REQUESTED);
+ − break;
+ − default:
+ − TRACE_EVENT( "SIG_MG_SDA_START_EST unexpected for this NSAPI" );
+ − break;
+ − }
+ − }
+ − } /* for all nsapis */
+ −
+ − } /* sig_mg_sda_start_est() */
+ −
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : sig_pd_sda_data_ind
+ − +------------------------------------------------------------------------------
+ − | Description : Handles the signal PD_SD_DATA_IND
+ − |
+ − | Parameters : *ll_data_ind - Ptr to primitive payload
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − GLOBAL void sig_pda_sda_data_ind ( T_LL_DATA_IND *ll_data_ind )
+ − {
+ − UBYTE sapi_index = 0;
+ − BOOL valid = FALSE;
+ − UBYTE nsapi = 0;
+ − UBYTE sapi = 0;
+ −
+ − TRACE_FUNCTION( "sig_pda_sda_data_ind" );
+ −
+ − /*
+ − * set service instance according to sapi in primitive
+ − */
+ − sndcp_get_sapi_index(ll_data_ind->sapi, &sapi_index);
+ − sndcp_data->sda = & sndcp_data->sda_base[sapi_index];
+ − sda_get_nsapi(ll_data_ind, &nsapi);
+ −
+ − /*
+ − * LLC has now "used up" it's pending LL_GETDATA_REQ and will have
+ − * to wait for the next one.
+ − */
+ − sndcp_data->sda->llc_may_send = FALSE;
+ − sapi = ll_data_ind->sapi;
+ −
+ − switch( sndcp_get_nsapi_rec_state(nsapi) )
+ − {
+ − case SDA_ESTABLISH_REQUESTED:
+ − /*
+ − * Just discard the segment. Next segment will be requested after
+ − * confirmation of establishment.
+ − */
+ − PFREE(ll_data_ind);
+ − ll_data_ind = NULL;
+ − break;
+ −
+ − case SDA_RECEIVE_FIRST_SEGMENT:
+ − /*
+ − * Invalid segments are discarded without error notification
+ − */
+ − sda_is_seg_valid(ll_data_ind, &valid);
+ − if (!valid) {
+ − PFREE(ll_data_ind);
+ − sda_get_data_if_nec(sapi);
+ − return;
+ − }
+ − if (sda_f_bit(ll_data_ind)) {
+ − if (sda_m_bit(ll_data_ind)) {
+ − sda_ac_f_f1_m1(ll_data_ind);
+ − } else {
+ − sda_ac_f_f1_m0(ll_data_ind);
+ − }
+ − } else {
+ − sda_ac_f_f0(ll_data_ind);
+ − }
+ −
+ − break;
+ −
+ − case SDA_RECEIVE_SUBSEQUENT_SEGMENT:
+ − /*
+ − * Invalid segments are discarded without error notification
+ − */
+ − sda_is_seg_valid(ll_data_ind, &valid);
+ − if (!valid) {
+ − PFREE(ll_data_ind);
+ − sda_get_data_if_nec(sapi);
+ − return;
+ − }
+ − if (sda_f_bit(ll_data_ind)) {
+ − if (sda_m_bit(ll_data_ind)) {
+ − sda_ac_s_f1_m1(ll_data_ind);
+ − } else {
+ − sda_ac_s_f1_m0(ll_data_ind);
+ − }
+ − } else {
+ − if (sda_m_bit(ll_data_ind)) {
+ − sda_ac_s_f0_m1(ll_data_ind);
+ − } else {
+ − sda_ac_s_f0_m0(ll_data_ind);
+ − }
+ − }
+ −
+ − break;
+ −
+ − case SDA_WAIT_NSAPI:
+ − if (ll_data_ind != NULL)
+ − {
+ − PFREE(ll_data_ind);
+ − }
+ − sda_get_data_if_nec(sapi);
+ − break;
+ −
+ − case SDA_ACK_DISCARD:
+ − /*
+ − * In this state we will discard every downlink segment till we receive.
+ − * the last segment.
+ − * Once we receive the last segment, we will move to the state
+ − * SDA_RECEIVE_FIRST_SEGMENT.
+ − */
+ − TRACE_EVENT( "SDA_ACK_DISCARD state,Discard Segments ..." );
+ − sndcp_data->cur_segment_number[nsapi] ++;
+ − if (!sda_m_bit(ll_data_ind))
+ − {
+ − TRACE_EVENT( "Received the last Segment in SDA_ACK_DISCARD state " );
+ − sndcp_data->cur_segment_number[nsapi] = 0;
+ − sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT);
+ − }
+ − PFREE(ll_data_ind);
+ − sda_get_data_if_nec(sapi);
+ − break;
+ −
+ − default:
+ − TRACE_ERROR( "SIG_PDA_SDA_DATA_IND unexpected" );
+ − /*
+ − * The primitive LL_DATA_IND is unexpected or the
+ − * NSAPI value is wrong. Discard the prim and send a FC prim.
+ − */
+ − if (ll_data_ind != NULL)
+ − {
+ − PFREE(ll_data_ind);
+ − }
+ − sda_get_data_if_nec(sapi);
+ − break;
+ − }
+ −
+ − } /* sig_pda_sda_data_ind() */
+ −
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : sig_mg_sda_reset_ind
+ − +------------------------------------------------------------------------------
+ − | Description : Handles the internal signal SIG_MG_SDA_RESET_IND
+ − |
+ − | Parameters : affected sapi
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − GLOBAL void sig_mg_sda_reset_ind (UBYTE nsapi)
+ − {
+ −
+ − TRACE_ISIG( "sig_mg_sda_reset_ind" );
+ −
+ − switch( sndcp_get_nsapi_rec_state(nsapi) )
+ − {
+ − case SDA_ESTABLISH_REQUESTED:
+ − case SDA_RECEIVE_FIRST_SEGMENT:
+ − case SDA_RECEIVE_SUBSEQUENT_SEGMENT:
+ − case SDA_WAIT_NSAPI:
+ − case SDA_ACK_DISCARD:
+ − /*
+ − * Similar to sd.
+ − */
+ − sndcp_data->cur_dcomp[nsapi] = 0;
+ − sndcp_data->cur_pcomp[nsapi] = 0;
+ − break;
+ − default:
+ − TRACE_ERROR( "SIG_MG_SDA_RESET_IND unexpected" );
+ − break;
+ − }
+ − } /* sig_mg_sda_reset_ind() */
+ −