FreeCalypso > hg > fc-magnetite
diff src/g23m-fad/rlp/rlp_kerf.c @ 174:90eb61ecd093
src/g23m-fad: initial import from TCS3.2/LoCosto
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 12 Oct 2016 05:40:46 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/g23m-fad/rlp/rlp_kerf.c Wed Oct 12 05:40:46 2016 +0000 @@ -0,0 +1,2086 @@ +/* ++----------------------------------------------------------------------------- +| Project : GSM-F&D (8411) +| Modul : RLP_KERF ++----------------------------------------------------------------------------- +| Copyright 2002 Texas Instruments Berlin, AG +| All rights reserved. +| +| This file is confidential and a trade secret of Texas +| Instruments Berlin, AG +| The receipt of or possession of this file does not convey +| any rights to reproduce or disclose its contents or to +| manufacture, use, or sell anything it may describe, in +| whole, or in part, without the specific written consent of +| Texas Instruments Berlin, AG. ++----------------------------------------------------------------------------- +| Purpose : This Modul defines the procedures and functions for +| the component Radio Link Protocol of the mobile station ++----------------------------------------------------------------------------- +*/ + +#ifndef RLP_KERF_C +#define RLP_KERF_C +#endif + +#define ENTITY_RLP + +/*==== INCLUDES ===================================================*/ + +#include <string.h> +#include "typedefs.h" +#include "pconst.cdg" +#include "vsi.h" +#include "macdef.h" +#include "pconst.cdg" +#include "custom.h" +#include "gsm.h" +#include "cnf_rlp.h" +#include "mon_rlp.h" +#include "prim.h" +#include "pei.h" +#include "tok.h" +#include "ccdapi.h" +#include "rlp.h" + +/*==== CONST =======================================================*/ + +/*==== TYPES =======================================================*/ + +/*==== VAR EXPORT ==================================================*/ + +/*==== VAR LOCAL ===================================================*/ + +/*==== FUNCTIONS ===================================================*/ + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_initTRCVS | ++--------------------------------------------------------------------+ + + PURPOSE : Initialise the TCRVS table + +*/ + +LOCAL void ker_initTRCVS(T_RCVS_ENTRY *rcvsTab) +{ + T_FRAME_NUM lookUp; + + TRACE_FUNCTION ("ker_initTRCVS()"); + + for (lookUp = 0; lookUp < MAX_SREJ_COUNT; lookUp++) + { + rcvsTab[lookUp].isFree = TRUE; + rcvsTab[lookUp].slot = INVALID_IDX; + rcvsTab[lookUp].trcvs_running = FALSE; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_init | ++--------------------------------------------------------------------+ + + PURPOSE : initialise the rlp data for the kernel process + +*/ + +GLOBAL void ker_init(void) +{ + TRACE_FUNCTION ("ker_init()"); + + rlp_data->tul_rcv_running = FALSE; + + ker_initTRCVS(rlp_data->ker.rcvsTab); + + rlp_data->ker.DM_State = IS_IDLE; + rlp_data->ker.DM_FBit = 0; + + rbm_reset(&rlp_data->rbm); + + INIT_STATE(KER, RLP_ADM_AND_DETACHED); + INIT_STATE(KERXID_C, ISW_IDLE); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_get_xid_data | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +GLOBAL void ker_get_xid_data + ( + T_RLP_FRAMEDATA *raw_data, + UBYTE index, + T_RLP_XID_IND *xid_data, + BOOL ms_is_initiator, + ULONG *used_flags + ) +{ + UBYTE p_type; + UBYTE length; + UBYTE comp_request; + +#ifdef _SIMULATION_ + USHORT rcvd; + char trc_buf[80]; + UBYTE i, idx; + + strcpy (trc_buf, "get XID "); + idx = strlen(trc_buf); +#endif + + TRACE_FUNCTION ("ker_get_xid_data()"); + + rlp_data->ker.Rlp_Vers = DEF_RLP_VERS; + rlp_data->ker.K_ms_iwf = DEF_K_MS_IWF; + rlp_data->ker.K_iwf_ms = DEF_K_IWF_MS; + rlp_data->ker.T1 = rlp_data->ker.Def_T1; + rlp_data->ker.T2 = DEF_T2; + rlp_data->ker.N2 = DEF_N2; + rlp_data->ker.Pt = DEF_PT; + rlp_data->ker.P0 = DEF_P0; + rlp_data->ker.P1 = DEF_P1; + rlp_data->ker.P2 = DEF_P2; + + *used_flags = 0L; + + while (index < rlp_data->ker.FrameSize - HEADER_LEN - TRAILER_LEN) + { + length = raw_data[index] % 16; + p_type = (raw_data[index] - length) / 16; + + if (p_type EQ XID_T_NULL) + break; + +#ifdef _SIMULATION_ + for (i = 0; i < length+1; i++) + { + /*lint -e661 : Possible access of out-of-bounds pointer (1 beyond end of data) by operator 'unary * */ + HEX_BYTE (raw_data[index+i], &trc_buf[idx]); + /*lint +e661 */ + idx+=2; + } +#endif + + switch (p_type) + { + + case XID_T_T1: + rlp_data->ker.T1 = TIME_EXT2INT(raw_data[index+1]); +#ifdef _SIMULATION_ + rcvd = rlp_data->ker.T1; +#endif + if (rlp_data->ker.T1 < rlp_data->ker.Orig_T1) + rlp_data->ker.T1 = rlp_data->ker.Orig_T1; + *used_flags |= UF_SET_T1; + +#ifdef _SIMULATION_ + TRACE_EVENT_P2("RCVD XID T1 : %d -> %d", rcvd, rlp_data->ker.T1); +#endif + break; + + case XID_T_RLP_VERS: + rlp_data->ker.Rlp_Vers = raw_data[index+1]; +#ifdef _SIMULATION_ + rcvd = rlp_data->ker.Rlp_Vers; +#endif + if (rlp_data->ker.Rlp_Vers > ORIG_RLP_VERS) + rlp_data->ker.Rlp_Vers = ORIG_RLP_VERS; + + *used_flags |= UF_SET_RLP_VERS; +#ifdef _SIMULATION_ + TRACE_EVENT_P2("RCVD XID RLPV : %d -> %d", rcvd, rlp_data->ker.Rlp_Vers); +#endif + break; + + case XID_T_T2: + rlp_data->ker.T2 = TIME_EXT2INT(raw_data[index+1]); +#ifdef _SIMULATION_ + rcvd = rlp_data->ker.T2; +#endif + if (rlp_data->ker.T2 < rlp_data->ker.Orig_T2) + rlp_data->ker.T2 = rlp_data->ker.Orig_T2; + + *used_flags |= UF_SET_T2; +#ifdef _SIMULATION_ + TRACE_EVENT_P2("RCVD XID T2 : %d -> %d", rcvd, rlp_data->ker.T2); +#endif + break; + + case XID_T_K_MS_IWF: + rlp_data->ker.K_ms_iwf = raw_data[index+1]; +#ifdef _SIMULATION_ + rcvd = rlp_data->ker.K_ms_iwf; +#endif + if (rlp_data->ker.K_ms_iwf > rlp_data->ker.Orig_K_ms_iwf) + rlp_data->ker.K_ms_iwf = rlp_data->ker.Orig_K_ms_iwf; + + if (rlp_data->ker.Connected) + sbm_set_wind_size (rlp_data->ker.K_ms_iwf); + + *used_flags |= UF_SET_K_MS_IWF; +#ifdef _SIMULATION_ + TRACE_EVENT_P2("RCVD XID KMI : %d -> %d", rcvd, rlp_data->ker.K_ms_iwf); +#endif + break; + + case XID_T_N2: + rlp_data->ker.N2 = raw_data[index+1]; +#ifdef _SIMULATION_ + rcvd = rlp_data->ker.N2; +#endif + if (rlp_data->ker.N2 < rlp_data->ker.Orig_N2) + rlp_data->ker.N2 = rlp_data->ker.Orig_N2; + + sbm_set_retrans (rlp_data->ker.N2); + *used_flags |= UF_SET_N2; +#ifdef _SIMULATION_ + TRACE_EVENT_P2("RCVD XID N2 : %d -> %d", rcvd, rlp_data->ker.N2); +#endif + break; + + case XID_T_K_IWF_MS: + rlp_data->ker.K_iwf_ms = raw_data[index+1]; +#ifdef _SIMULATION_ + rcvd = rlp_data->ker.K_iwf_ms; +#endif + if (rlp_data->ker.K_iwf_ms > rlp_data->ker.Orig_K_iwf_ms) + rlp_data->ker.K_iwf_ms = rlp_data->ker.Orig_K_iwf_ms; + + if (rlp_data->ker.Connected) + if (rbm_set_wind_size (rlp_data->ker.K_iwf_ms)) + { + ker_reset_all_t_rcvs (); + srm_reset(); + } + + *used_flags |= UF_SET_K_IWF_MS; +#ifdef _SIMULATION_ + TRACE_EVENT_P2("RCVD XID KIM : %d -> %d", rcvd, rlp_data->ker.K_iwf_ms); +#endif + break; + + case XID_T_COMPR: + comp_request = raw_data[index+1] % 16; + rlp_data->ker.Pt = (raw_data[index+1] - comp_request) / 16; +#ifdef _SIMULATION_ + TRACE_EVENT_P1("RCVD XID PT : %d", rlp_data->ker.Pt); +#endif + + switch (comp_request) + { + case 0: + rlp_data->ker.P0 = RLP_COMP_DIR_NONE; + break; + + case 1: + if (ms_is_initiator) + { + if (rlp_data->ker.Orig_P0 EQ RLP_COMP_DIR_RECEIVE + OR rlp_data->ker.Orig_P0 EQ RLP_COMP_DIR_NONE) + rlp_data->ker.P0 = RLP_COMP_DIR_NONE; + else + rlp_data->ker.P0 = RLP_COMP_DIR_TRANSMIT; + } + else + { + if (rlp_data->ker.Orig_P0 EQ RLP_COMP_DIR_TRANSMIT + OR rlp_data->ker.Orig_P0 EQ RLP_COMP_DIR_NONE) + rlp_data->ker.P0 = RLP_COMP_DIR_NONE; + else + rlp_data->ker.P0 = RLP_COMP_DIR_RECEIVE; + } + break; + + case 2: + if (ms_is_initiator) + { + if (rlp_data->ker.Orig_P0 EQ RLP_COMP_DIR_TRANSMIT + OR rlp_data->ker.Orig_P0 EQ RLP_COMP_DIR_NONE) + rlp_data->ker.P0 = RLP_COMP_DIR_NONE; + else + rlp_data->ker.P0 = RLP_COMP_DIR_RECEIVE; + } + else + { + if (rlp_data->ker.Orig_P0 EQ RLP_COMP_DIR_RECEIVE + OR rlp_data->ker.Orig_P0 EQ RLP_COMP_DIR_NONE) + rlp_data->ker.P0 = RLP_COMP_DIR_NONE; + else + rlp_data->ker.P0 = RLP_COMP_DIR_TRANSMIT; + } + break; + + case 3: + rlp_data->ker.P0 = rlp_data->ker.Orig_P0; + break; + + } + +#ifdef _SIMULATION_ + TRACE_EVENT_P2("RCVD XID P0: %d -> %d", comp_request, rlp_data->ker.P0); +#endif + rlp_data->ker.P1 = (raw_data[index+3] * 256) + raw_data[index+2]; +#ifdef _SIMULATION_ + rcvd = rlp_data->ker.P1; +#endif + if (rlp_data->ker.P1 > rlp_data->ker.Orig_P1) + rlp_data->ker.P1 = rlp_data->ker.Orig_P1; + +#ifdef _SIMULATION_ + TRACE_EVENT_P2("RCVD XID P1: %d -> %d", rcvd, rlp_data->ker.P1); +#endif + + rlp_data->ker.P2 = raw_data[index+4]; +#ifdef _SIMULATION_ + rcvd = rlp_data->ker.P2; +#endif + if (rlp_data->ker.P2 > rlp_data->ker.Orig_P2) + rlp_data->ker.P2 = rlp_data->ker.Orig_P2; + + *used_flags |= UF_SET_COMPR; +#ifdef _SIMULATION_ + TRACE_EVENT_P2("RCVD XID P2 : %d -> %d", rcvd, rlp_data->ker.P2); +#endif + break; + } + index += (length+1); + } + + xid_data->rlp_vers = rlp_data->ker.Rlp_Vers; + xid_data->k_ms_iwf = rlp_data->ker.K_ms_iwf; + xid_data->k_iwf_ms = rlp_data->ker.K_iwf_ms; + + xid_data->t1 = TIME_INT2EXT (rlp_data->ker.T1); + xid_data->t2 = TIME_INT2EXT (rlp_data->ker.T2); + + xid_data->n2 = rlp_data->ker.N2; + xid_data->pt = rlp_data->ker.Pt; + xid_data->p0 = rlp_data->ker.P0; + xid_data->p1 = rlp_data->ker.P1; + xid_data->p2 = rlp_data->ker.P2; + +#ifdef _SIMULATION_ + trc_buf[idx] = '\0'; + TRACE_EVENT (trc_buf); +#endif +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_put_xid_data | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +GLOBAL void ker_put_xid_data + ( + T_RLP_FRAMEPTR l_Data, /* buffer for data */ + UBYTE index, /* start index in buffer */ + ULONG l_uf, /* valid parameters */ + BOOL ms_is_initiator, /* MS is sending XID*/ + UBYTE l_rlp_version, /* negotiated vers. */ + T_FRAME_NUM l_k_iwf_ms, /* winSize ms->iwf */ + T_FRAME_NUM l_k_ms_iwf, /* winSize iwf->ms */ + USHORT l_t1, /* ack timer value */ + UBYTE l_n2, /* num restransmiss */ + USHORT l_t2, /* reply delay */ + UBYTE l_pt, /* type data compr. */ + UBYTE l_p0, /* v42bis comp. req */ + USHORT l_p1, /* num possible code*/ + UBYTE l_p2 /* max encod. strlen*/ + ) +{ + register ULONG i; + + TRACE_FUNCTION ("ker_put_xid_data()"); + + i = index; + + if (((l_uf & UF_SET_RLP_VERS) EQ 0) OR (l_rlp_version < 1)) + { + l_uf &= ~UF_SET_COMPR; + } + + if (l_uf & UF_SET_RLP_VERS) + { + l_Data[i] = (XID_T_RLP_VERS * 16) + XID_L_RLP_VERS; + l_Data[i+1] = l_rlp_version; +#ifdef _SIMULATION_ + TRACE_EVENT_P1("SEND XID RLPV : %d", l_rlp_version); +#endif + i += (XID_L_RLP_VERS + 1); + } + + if (l_uf & UF_SET_K_IWF_MS) + { + l_Data[i] = (XID_T_K_IWF_MS * 16) + XID_L_K_IWF_MS; + l_Data[i+1] = (UBYTE) l_k_iwf_ms; +#ifdef _SIMULATION_ + TRACE_EVENT_P1("SEND XID KIM : %d", l_k_iwf_ms); +#endif + i += (XID_L_K_IWF_MS + 1); + } + + if (l_uf & UF_SET_K_MS_IWF) + { + l_Data[i] = (XID_T_K_MS_IWF * 16) + XID_L_K_MS_IWF; + l_Data[i+1] = (UBYTE) l_k_ms_iwf; +#ifdef _SIMULATION_ + TRACE_EVENT_P1("SEND XID KMI : %d", l_k_ms_iwf); +#endif + i += (XID_L_K_MS_IWF + 1); + } + + if (l_uf & UF_SET_T1) + { + l_Data[i] = (XID_T_T1 * 16) + XID_L_T1; + l_Data[i+1] = TIME_INT2EXT (l_t1); +#ifdef _SIMULATION_ + TRACE_EVENT_P1("SEND XID T1 : %d", l_t1); +#endif + i += (XID_L_T1 + 1); + } + + if (l_uf & UF_SET_N2) + { + l_Data[i] = (XID_T_N2 * 16) + XID_L_N2; + l_Data[i+1] = l_n2; +#ifdef _SIMULATION_ + TRACE_EVENT_P1("SEND XID N2 : %d", l_n2); +#endif + i += (XID_L_N2 + 1); + } + + if (l_uf & UF_SET_T2) + { + l_Data[i] = (XID_T_T2 * 16) + XID_L_T2; + l_Data[i+1] = TIME_INT2EXT (l_t2); +#ifdef _SIMULATION_ + TRACE_EVENT_P1("SEND XID T2 : %d", l_t2); +#endif + i += (XID_L_T2 + 1); + } + + if ( (l_uf & UF_SET_COMPR) AND !rlp_data->ker.Connected) + { + l_Data[i] = (XID_T_COMPR * 16) + XID_L_COMPR; + + switch (l_p0) + { + case RLP_COMP_DIR_NONE: + l_Data[i+1] = l_pt * 16; + break; + + case RLP_COMP_DIR_TRANSMIT: + if (ms_is_initiator) + l_Data[i+1] = (l_pt*16) + 1; + else + l_Data[i+1] = (l_pt*16) + 2; + break; + + case RLP_COMP_DIR_RECEIVE: + if (ms_is_initiator) + l_Data[i+1] = (l_pt*16) + 2; + else + l_Data[i+1] = (l_pt*16) + 1; + break; + + case RLP_COMP_DIR_BOTH: + l_Data[i+1] = (l_pt*16) + 3; + break; + } + l_Data[i+2] = (l_p1 % 256); + l_Data[i+3] = (l_p1 / 256); + l_Data[i+4] = l_p2; +#ifdef _SIMULATION_ + TRACE_EVENT_P1("SEND XID PT: %d", l_pt); + TRACE_EVENT_P2("SEND XID P0: %d -> %d", l_p0, l_Data[i+1] % 4); + TRACE_EVENT_P1("SEND XID P1: %d", l_p1); + TRACE_EVENT_P1("SEND XID P2: %d", l_p2); +#endif + i += (XID_L_COMPR + 1); + } + +#ifdef _SIMULATION_ + { + char trc_buf[80]; + U8 j, k; + + strcpy (trc_buf, "put XID "); + k = strlen(trc_buf); + for (j = index; j < i; j++) + { + /*lint -e661 : Possible access of out-of-bounds pointer (1 beyond end of data) by operator 'unary * */ + HEX_BYTE (l_Data[j], &trc_buf[k]); + /*lint +e661 */ + k += 2; + } + trc_buf[k] = '\0'; + TRACE_EVENT (trc_buf); + } +#endif + +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_check_low_water | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +LOCAL void ker_check_low_water(void) +{ + TRACE_FUNCTION ("ker_check_low_water()"); + + if (sbm_space_in_buf () >= rlp_data->ker.FramesPerPrim) + { + if (rlp_data->ker.UL_Snd_State EQ IW_IDLE) + { + PALLOC (rlp_ready_ind, RLP_READY_IND); + + PSENDX (L2R, rlp_ready_ind); + rlp_data->ker.UL_Snd_State = IW_WAIT; + } + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_get_send_frame | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +LOCAL void ker_get_send_frame + ( + T_FRAME_DESC *frameDesc, + T_FRAME_NUM *frameNo, + BOOL *frameFound + ) +{ + BOOL framesCouldBeSent; + + TRACE_FUNCTION ("ker_get_send_frame()"); + + if (rlp_data->ker.RRReady) + { + sbm_get_frame + ( + frameDesc, + frameNo, + &framesCouldBeSent, + frameFound + ); + + if (framesCouldBeSent) + ker_check_low_water (); + } + else + { + /* + * remote receiver can not accept data + */ + *frameFound = FALSE; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_startTRCVS | ++--------------------------------------------------------------------+ + + PURPOSE : Start the timer TRCVS for a slot + +*/ + +LOCAL void ker_startTRCVS(T_FRAME_NUM slot) +{ + T_FRAME_NUM lookUp; + + TRACE_FUNCTION ("ker_startTRCVS()"); + + for (lookUp = 0; lookUp < MAX_SREJ_COUNT; lookUp++) + { + if (rlp_data->ker.rcvsTab[lookUp].isFree) + { + rlp_data->ker.rcvsTab[lookUp].slot = slot; + TIMERSTART(lookUp, rlp_data->ker.T1); + rlp_data->ker.rcvsTab[lookUp].trcvs_running = TRUE; + rlp_data->ker.rcvsTab[lookUp].isFree = FALSE; + return; + } + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_send_srej_sreji_cmd | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +LOCAL void ker_send_srej_sreji_cmd(T_FRAME_NUM slot) +{ + T_FRAME_DESC frameDesc; + T_FRAME_NUM frame; + BOOL frameFound; + + + rlp_data->ker.DTX_SF = DTX_N; + + TRACE_FUNCTION ("ker_send_srej_sreji_cmd()"); + + if (rlp_data->ker.Poll_xchg NEQ IW_WAIT + AND rlp_data->ker.Poll_State EQ ISW_SEND) + { + sig_ker_snd_srej_req (1, 1, slot); + rbm_set_rslot_wait (slot); + + ker_startTRCVS (slot); + + srm_count (slot); + + rlp_data->ker.SREJ_Count++; + rlp_data->ker.Poll_Count++; + rlp_data->ker.Poll_State = ISW_WAIT; + rlp_data->ker.Poll_xchg = IW_WAIT; + + TIMERSTART (TT_HANDLE, rlp_data->ker.T1); + } + else + { + ker_get_send_frame (&frameDesc, &frame, &frameFound); + + if (frameFound) + { + sig_ker_snd_srej_i_req (1, 0, slot, frame, &frameDesc); + + rbm_set_rslot_wait (slot); + + ker_startTRCVS (slot); + + srm_count (slot); + + rlp_data->ker.SREJ_Count++; + + TIMERSTART (TT_HANDLE, rlp_data->ker.T1); + } + else + { + sig_ker_snd_srej_req (1, 0, slot); + + rbm_set_rslot_wait (slot); + + ker_startTRCVS (slot); + + srm_count (slot); + + rlp_data->ker.SREJ_Count++; + } + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_send_rej_reji_cmd | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +LOCAL void ker_send_rej_reji_cmd + ( + T_FRAME_NUM vr + ) +{ + T_FRAME_DESC frameDesc; + T_FRAME_NUM frame; + BOOL frameFound; + + TRACE_FUNCTION ("ker_send_rej_reji_cmd()"); + + rlp_data->ker.DTX_SF = DTX_N; + + if (rlp_data->ker.Poll_xchg NEQ IW_WAIT AND rlp_data->ker.Poll_State EQ ISW_SEND) + { + sig_ker_snd_rej_req (1, 1, vr); + + rlp_data->ker.Ackn_State = IS_IDLE; + rlp_data->ker.REJ_State = ISW_WAIT; + + TIMERSTART + ( + TRCVR_HANDLE, + rlp_data->ker.T1 + ); + rlp_data->ker.Poll_Count++; + rlp_data->ker.Poll_State = ISW_WAIT; + rlp_data->ker.Poll_xchg = IW_WAIT; + + TIMERSTART (TT_HANDLE, rlp_data->ker.T1); + } + else + { + ker_get_send_frame (&frameDesc, &frame, &frameFound); + + if (frameFound) + { + sig_ker_snd_rej_i_req (1, 0, vr, frame, &frameDesc); + + TIMERSTART (TT_HANDLE, rlp_data->ker.T1); + } + else + sig_ker_snd_rej_req (1, 0, vr); + + TIMERSTART(TRCVR_HANDLE, rlp_data->ker.T1); + rlp_data->ker.Ackn_State = IS_IDLE; + rlp_data->ker.REJ_State = ISW_WAIT; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_send_rnr_rnri_cmd | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +LOCAL void ker_send_rnr_rnri_cmd + ( + T_FRAME_NUM vr + ) +{ + T_FRAME_DESC frameDesc; + T_FRAME_NUM frame; + BOOL frameFound; + + TRACE_FUNCTION ("ker_send_rnr_rnri_cmd()"); + + if (rlp_data->ker.Poll_xchg NEQ IW_WAIT + AND rlp_data->ker.Poll_State EQ ISW_SEND) + { + sig_ker_snd_rnr_req (1, 1, vr, 0); + + rlp_data->ker.Ackn_State = IS_IDLE; + rlp_data->ker.Poll_Count++; + rlp_data->ker.Poll_State = ISW_WAIT; + rlp_data->ker.Poll_xchg = IW_WAIT; + + rlp_data->ker.DTX_SF = DTX_N; + + TIMERSTART (TT_HANDLE, rlp_data->ker.T1); + } + else + { + ker_get_send_frame (&frameDesc, &frame, &frameFound); + + if (frameFound) + { + sig_ker_snd_rnr_i_req (1, 0, vr, frame, &frameDesc); + + rlp_data->ker.Ackn_State = IS_IDLE; + + rlp_data->ker.DTX_SF = DTX_N; + + TIMERSTART (TT_HANDLE, rlp_data->ker.T1); + } + else + { + if (rlp_data->ker.Ackn_State EQ IS_IDLE + AND rlp_data->ker.DTX_SF EQ DTX_RNR + AND rlp_data->ker.DTX_VR EQ vr) + { + sig_ker_snd_rnr_req (1, 0, vr, 1); + } + else + { + sig_ker_snd_rnr_req (1, 0, vr, 0); + + rlp_data->ker.Ackn_State = IS_IDLE; + rlp_data->ker.DTX_SF = DTX_RNR; + rlp_data->ker.DTX_VR = vr; + } + } + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_send_rr_rri_cmd | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +LOCAL void ker_send_rr_rri_cmd + ( + T_FRAME_NUM vr + ) +{ + T_FRAME_DESC frameDesc; + T_FRAME_NUM frame; + BOOL frameFound; + + TRACE_FUNCTION ("ker_send_rr_rri_cmd()"); + + if (rlp_data->ker.Poll_xchg NEQ IW_WAIT AND rlp_data->ker.Poll_State EQ ISW_SEND) + { + +#ifdef ENABLE_DTX + sig_ker_snd_rr_req (1, 1, vr, 0); +#else + sig_ker_snd_rr_req (1, 1, vr); +#endif + + rlp_data->ker.Ackn_State = IS_IDLE; + rlp_data->ker.Poll_Count++; + rlp_data->ker.Poll_State = ISW_WAIT; + rlp_data->ker.Poll_xchg = IW_WAIT; + + rlp_data->ker.DTX_SF = DTX_N; + + TIMERSTART (TT_HANDLE, rlp_data->ker.T1); + } + else + { + ker_get_send_frame (&frameDesc, &frame, &frameFound); + + if (frameFound) + { + sig_ker_snd_rr_i_req (1, 0, vr, frame, &frameDesc); + + rlp_data->ker.Ackn_State = IS_IDLE; + + TIMERSTART (TT_HANDLE, rlp_data->ker.T1); + rlp_data->ker.DTX_SF = DTX_N; + + } + else + { + if (rlp_data->ker.Ackn_State EQ IS_IDLE + AND rlp_data->ker.DTX_SF EQ DTX_RR + AND rlp_data->ker.DTX_VR EQ vr) + { +#ifdef ENABLE_DTX + sig_ker_snd_rr_req (1, 0, vr, 1); +#else + sig_ker_snd_rr_req (1, 0, vr); +#endif + } + else + { +#ifdef ENABLE_DTX + sig_ker_snd_rr_req (1, 0, vr, 0); +#else + sig_ker_snd_rr_req (1, 0, vr); +#endif + rlp_data->ker.Ackn_State = IS_IDLE; + rlp_data->ker.DTX_SF = DTX_RR; + rlp_data->ker.DTX_VR = vr; + } + } + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_send_rnr_rnri_resp | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +LOCAL void ker_send_rnr_rnri_resp + ( + T_FRAME_NUM vr + ) +{ + + TRACE_FUNCTION ("ker_send_rnr_rnri_resp()"); + + sig_ker_snd_rnr_req (0, 1, vr, 0); + + rlp_data->ker.Ackn_State = IS_IDLE; + rlp_data->ker.Ackn_FBit = 0; + rlp_data->ker.DTX_SF = DTX_N; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_send_rr_rri_resp | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +LOCAL void ker_send_rr_rri_resp(T_FRAME_NUM vr) +{ + + TRACE_FUNCTION ("ker_send_rr_rri_resp()"); + +#ifdef ENABLE_DTX + sig_ker_snd_rr_req (0, 1, vr, 0); +#else + sig_ker_snd_rr_req (0, 1, vr); +#endif + + rlp_data->ker.Ackn_State = IS_IDLE; + rlp_data->ker.Ackn_FBit = 0; + rlp_data->ker.DTX_SF = DTX_N; + +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_copy_frame_to_sdu | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +GLOBAL void ker_copy_frame_to_sdu + ( + T_RLP_FRAMEPTR frame, + T_sdu *sdu + ) +{ + TRACE_FUNCTION ("ker_copy_frame_to_sdu()"); + + memcpy (sdu->buf+(sdu->o_buf>>3), frame, rlp_data->ker.FrameSize); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_copy_sdu_to_frame | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +GLOBAL void ker_copy_sdu_to_frame(T_sdu *sdu, T_RLP_FRAMEPTR frame, USHORT n) +{ + TRACE_FUNCTION ("ker_copy_sdu_to_frame()"); + + memcpy(frame, sdu->buf + (sdu->o_buf>>3) + (n * rlp_data->ker.FrameSize), + rlp_data->ker.FrameSize); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_get_frame_desc | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +GLOBAL void ker_get_frame_desc + ( + T_RLP_FRAMEPTR frame, + T_FRAME_DESC *frameDesc + ) +{ + TRACE_FUNCTION ("ker_get_frame_desc()"); + + frameDesc->Adr[0] = frame; + frameDesc->Len[0] = rlp_data->ker.FrameSize; + frameDesc->Adr[1] = (UBYTE *) NULL; + frameDesc->Len[1] = 0; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_handle_prim_send | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +LOCAL void ker_handle_prim_send(void) +{ + TRACE_FUNCTION ("ker_handle_prim_send()"); + + if (rlp_data->ker.UL_Rcv_State EQ IW_WAIT) + { + T_RLP_DATA_IND *rlp_data_ind; + + rbm_get_prim(&rlp_data_ind, &rlp_data->ker.LRReady, &rlp_data->ker.LRFull); + + PSENDX (L2R, rlp_data_ind); + rlp_data->ker.UL_Rcv_State = IW_IDLE; + TIMERSTOP (TUL_RCV_HANDLE); + rlp_data->tul_rcv_running = FALSE; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_stopTRCVS | ++--------------------------------------------------------------------+ + + PURPOSE : search the rcvs entry for a given timer handle. The + function stops the timer and returns the corresponding + slot. + +*/ + +LOCAL void ker_stopTRCVS + ( + T_FRAME_NUM slot + ) +{ + T_FRAME_NUM lookUp; + + TRACE_FUNCTION ("ker_stopTRCVS()"); + + for (lookUp = 0; lookUp < MAX_SREJ_COUNT; lookUp++) + { + if (!rlp_data->ker.rcvsTab[lookUp].isFree AND rlp_data->ker.rcvsTab[lookUp].slot EQ slot) + { + TIMERSTOP(lookUp); + rlp_data->ker.rcvsTab[lookUp].trcvs_running = FALSE; + rlp_data->ker.rcvsTab[lookUp].isFree = TRUE; + return; + } + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_i_handler | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +GLOBAL BOOL ker_i_handler(T_FRAME_NUM ns) +{ + TRACE_FUNCTION ("ker_i_handler()"); + + if (rlp_data->ker.LRFull) + { + /* + * ignore improper frame + * cBit and fBit are not considered + * at this stage + */ + return TRUE; + } + else + { + BOOL valid, expected, resetTimer, primToSend; + T_FRAME_NUM count; + + rbm_ns_check (ns, &valid, &expected); + + /* + * ns not within window? + */ + if (!valid) + { + /* + * ignore improper frame + */ + return TRUE; + } + + TIMERSTOP (TUL_RCV_HANDLE); /* optimisation trial... */ + /* + TRACE_EVENT("TIMERSTART TUL_RCV ker_i_handler"); + */ + TIMERSTART(TUL_RCV_HANDLE, rlp_data->ker.T_ul); + + if (expected) + { + rbm_accept_current_frame (); + rbm_set_rslot_rcvd (ns, &resetTimer); + + if (resetTimer) + { + ker_stopTRCVS (ns); + rlp_data->ker.SREJ_Count--; + srm_clear (ns); + } + + rbm_buffer_all_in_sequence_frames + ( + ns, + &primToSend, + &rlp_data->ker.LRReady, + &rlp_data->ker.LRFull + ); + + if (primToSend) + ker_handle_prim_send (); + + rlp_data->ker.REJ_State = ISW_IDLE; + TIMERSTOP (TRCVR_HANDLE); + rlp_data->ker.Ackn_State = IS_SEND; + return FALSE; + } + else + { + if (rlp_data->ker.REJ_State NEQ ISW_IDLE) + return TRUE; + /* + * ignore out of sequence frames + */ + + rbm_count_missing_i_frames (ns, &count); + + if (rlp_data->ker.SREJ_Count + (count-1) <=MAX_SREJ_COUNT) + { + rbm_move_current_frame (ns); + rbm_set_rslot_rcvd (ns, &resetTimer); + + if (resetTimer) + { + ker_stopTRCVS (ns); + rlp_data->ker.SREJ_Count--; + srm_clear (ns); + } + + rbm_mark_missing_i_frames_srej (ns); + + return FALSE; + } + else + { + rlp_data->ker.REJ_State = ISW_SEND; + return FALSE; + } + } + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_init_link_vars | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +GLOBAL void ker_init_link_vars + ( + void + ) +{ + TRACE_FUNCTION ("ker_init_link_vars()"); + + rlp_data->ker.UL_Rcv_State = IW_IDLE; + rlp_data->ker.UL_Snd_State = IW_IDLE; + rlp_data->ker.Ackn_State = IS_IDLE; + rlp_data->ker.Poll_State = ISW_IDLE; + rlp_data->ker.Poll_Count = 0; + rlp_data->ker.Poll_xchg = IW_IDLE; + rlp_data->ker.REJ_State = ISW_IDLE; + rlp_data->ker.SABM_State = ISW_IDLE; + rlp_data->ker.DISC_State = ISW_IDLE; + rlp_data->ker.RRReady = TRUE; + rlp_data->ker.LRReady = TRUE; + rlp_data->ker.LRFull = FALSE; + rlp_data->ker.SREJ_Count = 0; + rlp_data->ker.Connected = TRUE; + rlp_data->ker.DTX_SF = DTX_N; + + sbm_init + ( + rlp_data->ker.K_ms_iwf, + rlp_data->ker.FrameSize, + rlp_data->ker.N2 + ); + + rbm_init + ( + rlp_data->ker.K_iwf_ms, + rlp_data->ker.FrameSize, + rlp_data->ker.FramesPerPrim + ); + + srm_init (); + +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_requestxid | ++--------------------------------------------------------------------+ + + PURPOSE : This function is invoked to request an XID command. + Some variables are set, so that with next RA_READY_IND + a XID command is sent. + +*/ + +LOCAL void ker_requestxid(void) +{ + TRACE_FUNCTION ("ker_requestxid()"); + + SET_STATE(KERXID_C, ISW_SEND); + rlp_data->ker.XID_Count = 0; + rlp_data->ker.XID_C_PBit = 1; + + ker_put_xid_data + ( + rlp_data->ker.XID_C_Frame + HEADER_LEN, + 0, + UF_ALL, + TRUE, + ORIG_RLP_VERS, + rlp_data->ker.Orig_K_iwf_ms, + rlp_data->ker.Orig_K_ms_iwf, + rlp_data->ker.Orig_T1, + rlp_data->ker.Orig_N2, + rlp_data->ker.Orig_T2, + rlp_data->ker.Orig_Pt, + rlp_data->ker.Orig_P0, + rlp_data->ker.Orig_P1, + rlp_data->ker.Orig_P2 + ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERP | +| STATE : code ROUTINE : ker_init_xid_data | ++--------------------------------------------------------------------+ + + PURPOSE : initialize XID data from attach request + +*/ + +GLOBAL void ker_init_xid_data + ( + T_RLP_ATTACH_REQ *rlp_attach_req + ) +{ + TRACE_FUNCTION ("ker_init_xid_data()"); + + rlp_data->ker.Orig_K_ms_iwf = (U8)rlp_attach_req->k_ms_iwf; + rlp_data->ker.K_ms_iwf = DEF_K_MS_IWF; + + rlp_data->ker.Orig_K_iwf_ms = (U8)rlp_attach_req->k_iwf_ms; + rlp_data->ker.K_iwf_ms = DEF_K_IWF_MS; + + rlp_data->ker.Orig_T1 = TIME_EXT2INT (rlp_attach_req->t1); + rlp_data->ker.T1 = rlp_data->ker.Def_T1; + + /* + * >>>> According to GSM 11.10 V4.17.1 and V5.4.0 the default value must be used. + * >>>> Later versions specify, that the value is used, which MS wants to negotiate. + */ + /* use t1 immediately without negotiation, if it is greater than the default */ + /* + if (rlp_data->ker.Orig_T1 > rlp_data->ker.T1) + { + rlp_data->ker.T1 = rlp_data->ker.Orig_T1; + } + */ + /* + rlp_data->ker.Orig_T2 = TIME_EXT2INT (rlp_attach_req->t2); + */ + rlp_data->ker.Orig_T2 = 200; + rlp_data->ker.T2 = DEF_T2; + + rlp_data->ker.Orig_N2 = rlp_attach_req->n2; + rlp_data->ker.N2 = DEF_N2; + + rlp_data->ker.Orig_Pt = rlp_attach_req->pt; + rlp_data->ker.Pt = DEF_PT; + + rlp_data->ker.Orig_P0 = rlp_attach_req->p0; + rlp_data->ker.P0 = DEF_P0; + + rlp_data->ker.Orig_P1 = rlp_attach_req->p1; + rlp_data->ker.P1 = DEF_P1; + + rlp_data->ker.Orig_P2 = rlp_attach_req->p2; + rlp_data->ker.P2 = DEF_P2; + + rlp_data->ker.Rlp_Vers = ORIG_RLP_VERS; + + + if( !(rlp_data->ker.Orig_P0 EQ RLP_COMP_DIR_NONE AND + rlp_data->ker.Orig_K_ms_iwf EQ DEF_K_MS_IWF AND + rlp_data->ker.Orig_K_iwf_ms EQ DEF_K_IWF_MS AND + rlp_data->ker.Orig_T1 EQ rlp_data->ker.Def_T1 AND + /* + rlp_data->ker.Orig_T2 EQ DEF_T2 AND + */ + rlp_data->ker.Orig_N2 EQ DEF_N2 AND + rlp_data->ker.Orig_Pt EQ DEF_PT AND + rlp_data->ker.Orig_P0 EQ DEF_P0 AND + rlp_data->ker.Orig_P1 EQ DEF_P1 AND + rlp_data->ker.Orig_P2 EQ DEF_P2 )) + { + ker_requestxid (); + } + else + { + PALLOC (rlp_xid_ind, RLP_XID_IND); + + rlp_xid_ind->rlp_vers = rlp_data->ker.Rlp_Vers; + rlp_xid_ind->k_ms_iwf = rlp_data->ker.K_ms_iwf; + rlp_xid_ind->k_iwf_ms = rlp_data->ker.K_iwf_ms; + rlp_xid_ind->t1 = TIME_INT2EXT (rlp_data->ker.T1); + rlp_xid_ind->t2 = TIME_INT2EXT (rlp_data->ker.T2); + rlp_xid_ind->n2 = rlp_data->ker.N2; + rlp_xid_ind->pt = rlp_data->ker.Pt; + rlp_xid_ind->p0 = rlp_data->ker.P0; + rlp_xid_ind->p1 = rlp_data->ker.P1; + rlp_xid_ind->p2 = rlp_data->ker.P2; + + PSENDX (L2R, rlp_xid_ind); + } + +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_trace_rlp_frame | ++--------------------------------------------------------------------+ + + PURPOSE : traces the elements from the given RLP frame + +*/ + +#ifdef TRACE_RLP_FRAME + +GLOBAL void ker_trace_rlp_frame + ( + T_RLP_FRAMEPTR frame + ) +{ + T_BIT cBit; + T_BIT pFBit; + T_FRAME_NUM nr; + T_FRAME_NUM ns; + + T_RLP_DEBUG *deb = &rlp_data->deb; + + TRACE_FUNCTION ("ker_trace_rlp_frame()"); + + cBit = (T_BIT) (frame[0] & 1); + ns = (T_FRAME_NUM) ((frame[0] >> 3) | ((frame[1] & 1)<<5)); + pFBit = (T_BIT) ((frame[1] & 2)>>1); + + + deb->idx=0; + + deb->trc_buf[deb->idx++] = 'U'; + deb->trc_buf[deb->idx++] = ':'; + + switch (ns) + { + case 62: /* S-Frame */ + { + T_SF sFrame; + + nr = (T_FRAME_NUM) ((frame[1]>>2) & 0x3f); + + deb->trc_buf[deb->idx++] = 'S'; + deb->trc_buf[deb->idx++] = 'r'; + DEC_BYTE (nr, &deb->trc_buf[deb->idx]); deb->idx+=3; + deb->trc_buf[deb->idx++] = ' '; + + sFrame = (T_SF) ((frame[0]>>1) & 0x03); + + /* + * maybe optimize with a table!! + */ + switch (sFrame) + { + case SF_RR: + memcpy(&deb->trc_buf[deb->idx], "RR ",3); + break; + + case SF_RNR: + memcpy(&deb->trc_buf[deb->idx], "RNR",3); + break; + case SF_REJ: + memcpy(&deb->trc_buf[deb->idx], "REJ",3); + break; + case SF_SREJ: + memcpy(&deb->trc_buf[deb->idx], "SRJ",3); + break; + default: + memcpy(&deb->trc_buf[deb->idx], "***",3); + break; + + } + deb->idx+=3; + break; + } + + case 63: /* U-Frame */ + { + T_UF uFrame; + uFrame = (T_UF) ((frame[1]>>2) & 0x1f); + + deb->trc_buf[deb->idx++] = 'U'; + deb->trc_buf[deb->idx++] = ' '; + + /* + * maybe optimize with a table!! + */ + switch (uFrame) + { + case UF_NULL: + return; + + case UF_UI: + memcpy(&deb->trc_buf[deb->idx], "UI ",4); + break; + + case UF_DM: + memcpy(&deb->trc_buf[deb->idx], "DM ",4); + break; + + case UF_SABM: + memcpy(&deb->trc_buf[deb->idx], "SABM",4); + break; + + case UF_DISC: + memcpy(&deb->trc_buf[deb->idx], "DISC",4); + break; + + case UF_UA: + memcpy(&deb->trc_buf[deb->idx], "UA ",4); + break; + + case UF_XID: + memcpy(&deb->trc_buf[deb->idx], "XID ",4); + break; + + case UF_TEST: + memcpy(&deb->trc_buf[deb->idx], "TEST",4); + break; + + case UF_REMAP: + memcpy(&deb->trc_buf[deb->idx], "RMAP",4); + break; + + default: + memcpy(&deb->trc_buf[deb->idx], "****",4); + break; + } + nr = 0; + deb->idx += 4; + break; + } + + default: /* I+S-Frame */ + { + T_SF sFrame; + + nr = (T_FRAME_NUM) ((frame[1]>>2) & 0x3f); + + sFrame = (T_SF) ((frame[0]>>1) & 0x03); + + deb->trc_buf[deb->idx++] = 'I'; + deb->trc_buf[deb->idx++] = 'r'; + DEC_BYTE (nr, &deb->trc_buf[deb->idx]); deb->idx+=3; + deb->trc_buf[deb->idx++] = 's'; + DEC_BYTE (ns, &deb->trc_buf[deb->idx]); deb->idx+=3; + deb->trc_buf[deb->idx++] = ' '; + + /* + * maybe optimize with a table!! + */ + switch (sFrame) + { + case SF_RR: + memcpy(&deb->trc_buf[deb->idx], "RR ",3); + break; + + case SF_RNR: + memcpy(&deb->trc_buf[deb->idx], "RNR",3); + break; + case SF_REJ: + memcpy(&deb->trc_buf[deb->idx], "REJ",3); + break; + case SF_SREJ: + memcpy(&deb->trc_buf[deb->idx], "SRJ",3); + break; + default: + memcpy(&deb->trc_buf[deb->idx], "***",3); + break; + } + deb->idx += 3; + break; + } + } + deb->trc_buf[deb->idx++] = ' '; + deb->trc_buf[deb->idx++] = ((cBit) ? 'C' : 'R'); + deb->trc_buf[deb->idx++] = ((cBit) ? 'P' : 'F'); + deb->trc_buf[deb->idx++] = ' '; + HEX_BYTE (frame[1], &deb->trc_buf[deb->idx]); deb->idx+=2; + HEX_BYTE (frame[0], &deb->trc_buf[deb->idx]); deb->idx+=2; + deb->trc_buf[deb->idx++] = ' '; + HEX_BYTE (frame[2], &deb->trc_buf[deb->idx]); deb->idx+=2; + HEX_BYTE (frame[3], &deb->trc_buf[deb->idx]); deb->idx+=2; + + deb->trc_buf[deb->idx] = '\0'; + TRACE_EVENT (deb->trc_buf); +} +#endif + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_resetTRCVS | ++--------------------------------------------------------------------+ + + PURPOSE : Resets all running timer in the TCRVS table + +*/ + +LOCAL void ker_resetTRCVS + ( + void + ) +{ + T_FRAME_NUM lookUp; + + TRACE_FUNCTION ("ker_resetTRCVS()"); + + for (lookUp = 0; lookUp < MAX_SREJ_COUNT; lookUp++) + { + if (!rlp_data->ker.rcvsTab[lookUp].isFree AND rlp_data->ker.rcvsTab[lookUp].trcvs_running) + { + TIMERSTOP (lookUp); + rlp_data->ker.rcvsTab[lookUp].trcvs_running = FALSE; + rlp_data->ker.rcvsTab[lookUp].isFree = TRUE; + rlp_data->ker.rcvsTab[lookUp].slot = INVALID_IDX; + } + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_reset_all_t_rcvs | ++--------------------------------------------------------------------+ + + PURPOSE : Resets the timer for each rcvs slot. + +*/ + +GLOBAL void ker_reset_all_t_rcvs + ( + void + ) +{ + TRACE_FUNCTION ("ker_reset_all_t_rcvs()"); + + ker_resetTRCVS (); + + rlp_data->ker.SREJ_Count = 0; + + srm_reset (); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_s_handler | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +GLOBAL void ker_s_handler + ( + T_BIT cBit, + T_BIT pFBit, + T_SF sf, + T_FRAME_NUM nr, + BOOL *retransError + ) +{ + BOOL allFramesAck = FALSE; + + TRACE_FUNCTION ("ker_s_handler()"); + + *retransError = FALSE; + + if (cBit EQ 1 AND pFBit EQ 1) + { + rlp_data->ker.Ackn_State = IS_SEND; + rlp_data->ker.Ackn_FBit = 1; + + rbm_reset_all_r_states (); + ker_reset_all_t_rcvs (); + rlp_data->ker.REJ_State = ISW_IDLE; + + TIMERSTOP (TRCVR_HANDLE); + } + + if (rlp_data->ker.Poll_State NEQ ISW_IDLE) + { + if (pFBit EQ 0 OR sf EQ SF_REJ OR sf EQ SF_SREJ ) + return; + + sbm_rej_from_n (nr, retransError); + rlp_data->ker.Poll_State = ISW_IDLE; + rlp_data->ker.Poll_xchg = IW_IDLE; + rlp_data->ker.Poll_Count = 0; + + if (*retransError) + { + ker_reset_all_t_rcvs (); + rbm_reset_srej_slots (); + + TIMERSTOP (TRCVR_HANDLE); + TIMERSTOP (TT_HANDLE); + + rlp_data->ker.DISC_State = ISW_SEND; + rlp_data->ker.DISC_Count = 0; + + + if (rlp_data->ker.Poll_xchg EQ IW_IDLE) + rlp_data->ker.DISC_PBit = 1; + else + rlp_data->ker.DISC_PBit = 0; + + ker_deinit_link_vars(); + rlp_data->ker.DISC_Ind = TRUE; + + return; + } + } + + switch (sf) + { + case SF_RR: + allFramesAck = sbm_ack_upto_n(nr); + if (rlp_data->ker.RRReady EQ FALSE) + { + TRACE_EVENT ("Remote RR"); + } + rlp_data->ker.RRReady = TRUE; + break; + + case SF_RNR: + allFramesAck = sbm_ack_upto_n(nr); + if (rlp_data->ker.RRReady EQ TRUE) + { + TRACE_EVENT ("Remote RNR"); + } + rlp_data->ker.RRReady = FALSE; + break; + + case SF_REJ: + allFramesAck = sbm_ack_upto_n(nr); + sbm_rej_from_n (nr, retransError); + + if(*retransError) + { + ker_reset_all_t_rcvs (); + rbm_reset_srej_slots (); + + TIMERSTOP (TRCVR_HANDLE); + TIMERSTOP (TT_HANDLE); + + rlp_data->ker.DISC_State = ISW_SEND; + rlp_data->ker.DISC_Count = 0; + + if (rlp_data->ker.Poll_xchg EQ IW_IDLE) + rlp_data->ker.DISC_PBit = 1; + else + rlp_data->ker.DISC_PBit = 0; + + ker_deinit_link_vars(); + rlp_data->ker.DISC_Ind = TRUE; + + return; + } + + if (rlp_data->ker.RRReady EQ FALSE) + { + TRACE_EVENT ("Remote RR"); + } + rlp_data->ker.RRReady = TRUE; + break; + + case SF_SREJ: + sbm_srej_frame (nr); + TIMERSTOP (TT_HANDLE); + return; + } + + if (allFramesAck) + { + TIMERSTOP (TT_HANDLE); + } + +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_send_data | ++--------------------------------------------------------------------+ + + PURPOSE : +*/ + +GLOBAL void ker_send_data(void) +{ + T_EXT_FRAME_NUM slot; + T_FRAME_NUM vr; + + TRACE_FUNCTION ("ker_send_data()"); + + if (rlp_data->ker.UA_State EQ IS_SEND) + { + sig_ker_snd_ua_req (rlp_data->ker.UA_FBit); + rlp_data->ker.UA_State = IS_IDLE; + } + else + { + vr = rbm_get_vr(); + if (rlp_data->ker.Ackn_FBit EQ 1) + { + if (rlp_data->ker.LRReady) + ker_send_rr_rri_resp (vr); + else + ker_send_rnr_rnri_resp (vr); + } + else + { + switch (rlp_data->ker.REJ_State) + { + case ISW_SEND: + ker_send_rej_reji_cmd (vr); + break; + + default: + slot = rbm_check_slots_srej(); + if (slot EQ INVALID_IDX) + { + if (rlp_data->ker.LRReady) + ker_send_rr_rri_cmd (vr); + else + ker_send_rnr_rnri_cmd (vr); + } + else + ker_send_srej_sreji_cmd (slot); + break; + } + } + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_send_txu | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +GLOBAL BOOL ker_send_txu + ( + void + ) +{ + TRACE_FUNCTION ("ker_send_txu()"); + + if (rlp_data->ker.TEST_R_State EQ IS_SEND) + { + sig_ker_snd_test_req + ( + 0, + rlp_data->ker.TEST_R_FBit, + &rlp_data->ker.TEST_R_FrameDesc + ); + rlp_data->ker.TEST_R_State = IS_IDLE; + return TRUE; + } + + if (rlp_data->ker.XID_R_State EQ IS_SEND) + { + TRACE_EVENT ("Snd XID R"); + sig_ker_snd_xid_req + ( + 0, + 1, + &rlp_data->ker.XID_R_FrameDesc + ); + + rlp_data->ker.XID_R_State = IS_IDLE; + return TRUE; + } + + if (GET_STATE(KERXID_C) EQ ISW_SEND) + { + if (rlp_data->ker.Poll_xchg NEQ IW_WAIT) + { + TRACE_EVENT ("Snd XID C"); + sig_ker_snd_xid_req + ( + 1, + 1, + &rlp_data->ker.XID_C_FrameDesc + ); + SET_STATE(KERXID_C, ISW_WAIT); + + TIMERSTART(TXID_HANDLE, rlp_data->ker.T1); + rlp_data->ker.Poll_xchg = IW_WAIT; + return TRUE; + } + } + + if (rlp_data->ker.UI_State EQ IS_SEND) + { + sig_ker_snd_ui_req + ( + 1, + 0, + &rlp_data->ker.UI_FrameDesc + ); + rlp_data->ker.UI_State = IS_IDLE; + return TRUE; + } + + return FALSE; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_deinit_link_vars | ++--------------------------------------------------------------------+ + + PURPOSE : deinitialize send/receive buffer manager, + +*/ + +GLOBAL void ker_deinit_link_vars + ( + void + ) +{ + + TRACE_FUNCTION ("ker_deinit_link_vars()"); + + rlp_data->ker.Connected = FALSE; + + sbm_deinit (); + + rbm_deinit (); + + srm_deinit (); + +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_send_rlp_error_ind | ++--------------------------------------------------------------------+ + + PURPOSE : send a error cause to L2R + +*/ + +GLOBAL void ker_send_rlp_error_ind(USHORT cause) +{ + PALLOC (rlp_error_ind, RLP_ERROR_IND); + + TRACE_FUNCTION ("ker_send_rlp_error_ind()"); + TRACE_EVENT_P1("RLP Error : %d", cause); + + rlp_error_ind->cause = cause; + PSENDX (L2R, rlp_error_ind); + ker_deinit_link_vars (); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_getSlotTRCVS | ++--------------------------------------------------------------------+ + + PURPOSE : search the rcvs entry for a given timer handle. The + function returns the corresponding slot. The entry + is freed. This function is used in the timeout handling + functions of the entity. + +*/ +GLOBAL T_FRAME_NUM ker_getSlotTRCVS (USHORT index) +{ + rlp_data->ker.rcvsTab[index].trcvs_running = FALSE; + rlp_data->ker.rcvsTab[index].isFree = TRUE; + + return rlp_data->ker.rcvsTab[index].slot; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_fill_remap_frame | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +GLOBAL void ker_fill_remap_frame + ( + T_FRAME_NUM vr + ) +{ + + TRACE_FUNCTION ("ker_fill_remap_frame()"); + + rlp_data->ker.REMAP_Frame[HEADER_LEN + 0] = vr * 4; + rlp_data->ker.REMAP_Frame[HEADER_LEN + 1] = 0; + + ker_put_xid_data + ( + rlp_data->ker.REMAP_Frame + HEADER_LEN, + 2, + UF_ALL, + TRUE, + ORIG_RLP_VERS, + rlp_data->ker.Orig_K_iwf_ms, + rlp_data->ker.Orig_K_ms_iwf, + rlp_data->ker.Orig_T1, + rlp_data->ker.Orig_N2, + rlp_data->ker.Orig_T2, + rlp_data->ker.Orig_Pt, + rlp_data->ker.Orig_P0, + rlp_data->ker.Orig_P1, + rlp_data->ker.Orig_P2 + ); + +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_send_remap_data | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +GLOBAL BOOL ker_send_remap_data + ( + void + ) +{ + T_RLP_DATA_REQ *prim; + + TRACE_FUNCTION ("ker_send_remap_data()"); + + if (sbm_recall_prim (&prim)) + { + PPASS (prim, rlp_remap_data_ind, RLP_REMAP_DATA_IND); + rlp_remap_data_ind->data_size = rlp_data->ker.OldFrameSize - HEADER_LEN - TRAILER_LEN; + PSENDX (L2R, rlp_remap_data_ind); + return TRUE; + } + return FALSE; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : RLP_KERF | +| STATE : code ROUTINE : ker_set_frame_size | ++--------------------------------------------------------------------+ + + PURPOSE : + +*/ + +GLOBAL void ker_set_frame_size + ( + UBYTE rate + ) +{ + + TRACE_FUNCTION ("ker_set_frame_size()"); + + switch(rate) + { + case RLP_FULLRATE_14400: + rlp_data->ker.Def_T1 = DEF_T1_FR14400; + rlp_data->ker.FrameSize = FRAME_SIZE_LONG; + break; + case RLP_FULLRATE_9600: + rlp_data->ker.Def_T1 = DEF_T1_FR9600; + rlp_data->ker.FrameSize = FRAME_SIZE_SHORT; + break; + case RLP_FULLRATE_4800: + rlp_data->ker.Def_T1 = DEF_T1_FR4800; + rlp_data->ker.FrameSize = FRAME_SIZE_SHORT; + break; + case RLP_HALFRATE_4800: + rlp_data->ker.Def_T1 = DEF_T1_HR4800; + rlp_data->ker.FrameSize = FRAME_SIZE_SHORT; + break; + } + + rlp_data->ker.FramesPerPrim = + (rlp_data->ker.BytesPerPrim + rlp_data->ker.FrameSize - 1) / + rlp_data->ker.FrameSize; + + sig_ker_snd_set_frame_size_req (rlp_data->ker.FrameSize); + +} +