FreeCalypso > hg > fc-tourmaline
view src/g23m-fad/l2r/l2r_dnf.c @ 19:aa868a5dcfd7
blobs: very few!
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 16 Oct 2020 07:38:28 +0000 |
parents | fa8dc04885d8 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : CSD (8411) | Modul : L2r_dnf.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 defines the procedures and functions for | the component L2R of the base station +----------------------------------------------------------------------------- */ #ifndef L2R_DNF_C #define L2R_DNF_C #endif #define ENTITY_L2R /*==== INCLUDES ===================================================*/ #include <string.h> #include "typedefs.h" #include "pconst.cdg" #include "vsi.h" #include "macdef.h" #include "custom.h" #include "gsm.h" #include "cus_l2r.h" #include "cnf_l2r.h" #include "mon_l2r.h" #include "prim.h" #include "pei.h" #include "tok.h" #include "dti.h" /* functionality of the dti library */ #include "cl_ribu.h" #include "l2r.h" /*==== CONST =======================================================*/ /*==== TYPES =======================================================*/ /*==== VAR EXPORT ==================================================*/ /*==== VAR LOCAL ===================================================*/ /*==== FUNCTIONS ===================================================*/ /* +------------------------------------------------------------------------------ | Function : dn_init +------------------------------------------------------------------------------ | Description : initialise the l2r data for the downlink process | | Parameters : - | | | Return : - +------------------------------------------------------------------------------ */ GLOBAL void dn_init(T_DN *ddn) { TRACE_FUNCTION ("dn_init()"); ddn->FlowCtrlUsed = FALSE; ddn->DnFlow = FL_INACTIVE; ddn->UpFlow = FL_INACTIVE; #ifdef L2R_TRACE_FLOW ddn->LastSentFlow = FL_INVALID; #endif ddn->FlowThresh = MAX_DPRIM_RIBU_SIZE / 2; ddn->LastState = 0 << SO_SA_BIT | 0 << SO_SB_BIT; ddn->RiBu.idx.depth = MAX_DPRIM_RIBU_SIZE; INIT_STATE (DN_LL, IW_IDLE); INIT_STATE (DN_UL, IW_IDLE); INIT_STATE (DN, DN_DISCONNECTED); } /* +------------------------------------------------------------------------------ | Function : dn_check_flow +------------------------------------------------------------------------------ | Description : checks flow control staus | | Parameters : - | | | Return : - +------------------------------------------------------------------------------ */ GLOBAL void dn_check_flow(void) { T_DN *ddn = &l2r_data->dn; TRACE_FUNCTION ("dn_check_flow()"); if (!ddn->FlowCtrlUsed) { return; } if (ddn->RiBu.idx.filled >= ddn->FlowThresh) { switch (ddn->DnFlow) { case FL_ACTIVE: return; case FL_INACTIVE: ddn->DnFlow = FL_ACTIVE; break; } } else { switch (ddn->DnFlow) { case FL_ACTIVE: ddn->DnFlow = FL_INACTIVE; break; case FL_INACTIVE: return; } } sig_dn_up_flow (ddn->DnFlow); } /* +------------------------------------------------------------------------------ | Function : dn_next_frame +------------------------------------------------------------------------------ | Description : Local function, which is used by up_copy_data_from_l2r | to advance to the next frame in the primitive. | The variable primDesc of the calling function is updated. | | Parameters : primDesc - | | Return : 1 - | 0 - +------------------------------------------------------------------------------ */ LOCAL UBYTE dn_next_frame(T_P_DPRIM_DESCRIPTOR *primDesc) { T_DN *ddn = &l2r_data->dn; #ifdef _SIMULATION_ TRACE_FUNCTION ("dn_next_frame()"); #endif (*primDesc)->index++; /* next frame */ if ((*primDesc)->index >= (*primDesc)->nFr) { #ifdef _SIMULATION_ TRACE_EVENT ("next primitive"); #endif cl_ribu_read_index(&ddn->RiBu.idx); /* point to next primitive */ if (!ddn->RiBu.idx.filled) /* no primitive is ready */ { #ifdef _SIMULATION_ TRACE_EVENT ("no primitive is ready"); #endif return (0); } *primDesc = ddn->RiBu._primDesc[ddn->RiBu.idx.ri]; /* point to next primitive descriptor */ (*primDesc)->index = 0; } return (1); } /* +------------------------------------------------------------------------------ | Function : dn_copy_data_from_l2r +------------------------------------------------------------------------------ | Description : Copies data from l2r into ring buffer. || Moreover the return value of the calling function | bytesCopied are set | Parameters : buf - | len - | sa - | sb - | flow - | bytesCopied - | | Return : - +------------------------------------------------------------------------------ */ LOCAL U16 dn_copy_data_from_l2r(U8 *buf, U16 len, U8 *sa, U8 *sb, U8 *flow) { T_DN *ddn = &l2r_data->dn; T_P_DPRIM_DESCRIPTOR primDesc; T_P_L2R_FRAME frame; register T_P_UBYTE pFrame; register T_P_UBYTE pBuf; register T_P_UBYTE pStat; USHORT bytesToCopy; USHORT blocklen; UBYTE frameCount; UBYTE statOct; #ifdef _SIMULATION_ TRACE_EVENT ("dn_copy_data_from_l2r()"); #endif ddn->ReportMrgFlow = FALSE; if (!ddn->RiBu.idx.filled) /* don't copy into buffer if no primitive is ready */ { #ifdef _SIMULATION_ TRACE_EVENT ("no primitive ready"); #endif switch (ddn->MrgFlow) { case FL_ACTIVE: *flow = DTI_FLOW_OFF; break; case FL_INACTIVE: *flow = DTI_FLOW_ON; break; } *sa = GET_SO_SA_BIT(ddn->LastState); *sb = GET_SO_SB_BIT(ddn->LastState); return 0; } if (ddn->ULFlow EQ FL_ACTIVE) { len = 0; /* upper layer has raised flow control; don't send data */ } bytesToCopy = len; primDesc = ddn->RiBu._primDesc[ddn->RiBu.idx.ri]; /* point to current primitive descriptor */ if (primDesc->nFr EQ 0) /* skip empty primitive */ { #ifdef _SIMULATION_ TRACE_EVENT ("empty primitive"); #endif switch (ddn->MrgFlow) { case FL_ACTIVE: *flow = DTI_FLOW_OFF; break; case FL_INACTIVE: *flow = DTI_FLOW_ON; break; } *sa = GET_SO_SA_BIT(ddn->LastState); *sb = GET_SO_SB_BIT(ddn->LastState); return 0; } #ifdef _TARGET_ if (primDesc->prim->data_size > DATA_SIZE_SHORT) { frameCount = 1; } else { frameCount = 2; } #else { frameCount = 100; } #endif frame = (*primDesc->dadr)[primDesc->index]; /* dn_copy_data_from_l2r: point to current l2r frame in primitive */ pBuf = buf; /* point to destination buffer */ pFrame = &((*frame)[primDesc->offset]); pStat = &((*frame)[primDesc->off_status]); if (pFrame EQ pStat) { /* current byte is status octet */ ddn->LastState = *pFrame & SO_STATUS_BITS_MASK; } /* merge flow control conditions */ switch (ddn->MrgFlow) { case FL_ACTIVE: *flow = DTI_FLOW_OFF; break; case FL_INACTIVE: *flow = DTI_FLOW_ON; break; } *sa = GET_SO_SA_BIT(ddn->LastState); *sb = GET_SO_SB_BIT(ddn->LastState); /************************************************************************************ * loop until either * - no more data are available or * - status in L2R frame changes or * - buffer for data is full ************************************************************************************/ for (;;) { blocklen = pStat - pFrame; if (blocklen EQ 0) { /* * current byte is status octet; * only in the first pass of the loop, there may be no status octet */ /***************************** * evaluate status bits *****************************/ statOct = *pFrame; if (ddn->LastState NEQ (statOct & SO_STATUS_BITS_MASK)) { /* * Status has changed. * We have to stop, * since only one state can be transmitted to the upper layer. */ primDesc->offset = primDesc->off_status = pFrame - (T_P_UBYTE)frame; #ifdef _SIMULATION_ TRACE_EVENT ("return because of status change"); #endif return len - bytesToCopy; } pFrame++; /************************************ * evaluate address bits ************************************/ statOct &= SO_ADR_MASK; switch (statOct) { case SO_BREAK_ACK: case SO_BREAK_REQ: case SO_END_EMPTY: /* * no more data in this frame */ if (dn_next_frame(&primDesc) EQ 0) /* no more data available */ { primDesc->offset = 0; primDesc->off_status = 0; #ifdef _SIMULATION_ TRACE_EVENT ("return because no more data available"); #endif return len - bytesToCopy; /* this much data could be copied */ } frameCount--; if (frameCount EQ 0) { primDesc->offset = 0; primDesc->off_status = 0; #ifdef _SIMULATION_ TRACE_EVENT ("return because number of frames reached"); #endif return len - bytesToCopy; /* this much data could be copied */ } frame = (*primDesc->dadr)[primDesc->index]; /* dn_copy_data_from_l2r */ pFrame = (T_P_UBYTE)frame; pStat = (T_P_UBYTE)frame; continue; /* continue with next frame */ case SO_END_FULL: pStat = &((*frame)[primDesc->prim->data_size]); blocklen = pStat - pFrame; break; case SO_TWO_OCTET: blocklen = *pFrame++ & SO_ADR_MASK_TWO_OCT; pStat = pFrame + blocklen; break; default: blocklen = statOct; pStat = pFrame + blocklen; break; } } if (bytesToCopy < blocklen) { /*************************************** * There is not enough space in the * buffer to copy the complete block ***************************************/ T_P_UBYTE pEnd = pFrame + bytesToCopy; /* save end mark */ while (pFrame < pEnd) { *pBuf++ = *pFrame++; } if (pFrame >= &((*frame)[primDesc->prim->data_size])) { /* * end of frame reached * actually this case can never occur, * since bytesToCopy < blocklen */ dn_next_frame(&primDesc); primDesc->offset = 0; primDesc->off_status = 0; } else { primDesc->offset = pFrame - (T_P_UBYTE)frame; primDesc->off_status = pStat - (T_P_UBYTE)frame; } #ifdef _SIMULATION_ TRACE_EVENT ("return because buffer is full"); #endif return len; /* this much data could be copied */ } else /* bytesToCopy >= blocklen */ { /*************************************** * Copy the complete block ***************************************/ bytesToCopy -= blocklen; while (pFrame < pStat) { *pBuf++ = *pFrame++; } if (pFrame >= &((*frame)[primDesc->prim->data_size])) /* end of frame reached */ { if (dn_next_frame(&primDesc) EQ 0) /* no more data available */ { #ifdef _SIMULATION_ TRACE_EVENT ("return because no more data available"); #endif return len - bytesToCopy; /* this much data could be copied */ } frameCount--; if (frameCount EQ 0) { primDesc->offset = 0; primDesc->off_status = 0; #ifdef _SIMULATION_ TRACE_EVENT ("return because number of frames reached"); #endif return len - bytesToCopy; /* this much data could be copied */ } frame = (*primDesc->dadr)[primDesc->index]; /* dn_copy_data_from_l2r */ pFrame = (T_P_UBYTE)frame; pStat = (T_P_UBYTE)frame; } if (bytesToCopy EQ 0) { primDesc->offset = pFrame - (T_P_UBYTE)frame; primDesc->off_status = pStat - (T_P_UBYTE)frame; #ifdef _SIMULATION_ TRACE_EVENT ("return because all data are copied"); #endif return len; /* this much data could be copied */ } } /* bytesToCopy >= blocklen */ } /* for (;;) */ } /* +------------------------------------------------------------------------------ | Function : dn_send_data_ind +------------------------------------------------------------------------------ | Description : This procedure copies data from the downlink ring buffer | into a DTI_DATA_IND primitive | and sends this primitive to the relay entity. | | Parameters : - | | | Return : - +------------------------------------------------------------------------------ */ GLOBAL void dn_send_data_ind(void) { T_DN *ddn = &l2r_data->dn; TRACE_FUNCTION ("dn_send_data_ind()"); if (ddn->DtiConnected EQ FALSE) { TRACE_EVENT("DTI not connected, but dn_send_data_ind() called"); return; } { USHORT len = L2R_FRAMES_PER_PRIM_MAX * (RLP_FRAME_SIZE_SHORT - HT_LEN - 1); UBYTE sa; UBYTE sb; UBYTE flow; T_desc2* desc; PALLOC (dti_data_ind, DTI2_DATA_IND); MALLOC (desc, (USHORT)(sizeof(T_desc2) - 1 + len)); desc->len = dn_copy_data_from_l2r ((U8*)&desc->buffer[0], len, &sa, &sb, &flow); desc->size = desc->len; desc->offset = 0; desc->next = 0; dti_data_ind->desc_list2.first = (ULONG)desc; dti_data_ind->desc_list2.list_len = desc->len; dti_data_ind->parameters.st_lines.st_line_sa = sa; dti_data_ind->parameters.st_lines.st_line_sb = sb; dti_data_ind->parameters.st_lines.st_flow = flow; dti_data_ind->parameters.st_lines.st_break_len = DTI_BREAK_OFF; dti_data_ind->parameters.p_id = DTI_PID_UOS; dti_data_ind->link_id = ddn->link_id; #ifdef L2R_TRACE_FLOW if (ddn->LastSentFlow NEQ dti_data_ind->parameters.st_lines.st_flow) { switch (dti_data_ind->parameters.st_lines.st_flow) { case FL_ACTIVE: TRACE_EVENT("DTI downlink: FL_ACTIVE"); break; case FL_INACTIVE: TRACE_EVENT("DTI downlink: FL_INACTIVE"); break; } ddn->LastSentFlow = dti_data_ind->parameters.st_lines.st_flow; } #endif dti_send_data ( l2r_hDTI, L2R_DTI_UP_DEF_INSTANCE, L2R_DTI_UP_INTERFACE, L2R_DTI_UP_CHANNEL, dti_data_ind ); } } /* +------------------------------------------------------------------------------ | Function : dn_scan_break_req +------------------------------------------------------------------------------ | Description : This procedure scans a rlp_data_ind primitive for L2R BREAK | status octets. It returnes the index of the frame following | the last BREAK status octet in the primitive. | Moreover the total number of frames in the primitive | as well as the status bits of the last BREAK are returned. | In addition the x bit of the last status octet is returned. | It is important to search the last BREAK in the primitive, | because the data following a break signal | are used in the case of no data compression. | | Parameters : data_ind - | found | index | frames | emptyfr | sa | sb | flow_brk | flow_gen | | Return : - +------------------------------------------------------------------------------ */ GLOBAL void dn_scan_break_req ( T_P_RLP_DATA_IND data_ind, BOOL *found, T_PRIM_INDEX *index, T_PRIM_INDEX *frames, T_PRIM_INDEX *emptyfr, T_BIT *sa, T_BIT *sb, T_FLOW *flow_brk, T_FLOW *flow_gen ) { T_PRIM_INDEX ind; UBYTE off; UBYTE statOct; UBYTE brkStatOct = (UBYTE)(0 << SO_SA_BIT | 0 << SO_SB_BIT | 0 << SO_X_BIT); UBYTE genStatOct = (UBYTE)(0 << SO_SA_BIT | 0 << SO_SB_BIT | 0 << SO_X_BIT); T_P_L2R_FRAME frame; TRACE_FUNCTION ("dn_scan_break_req()"); *found = FALSE; *frames = data_ind->sdu.l_buf / (8 * data_ind->data_size + HT_LEN); *emptyfr = 0; frame = (T_P_L2R_FRAME)(data_ind->sdu.buf + (data_ind->sdu.o_buf>>3) + HEADER_LEN); off = 0; ind = 0; while (ind < *frames) { statOct = (*frame)[off]; switch (statOct & SO_ADR_MASK) { case SO_BREAK_REQ: *found = TRUE; *index = ind + 1; brkStatOct = statOct; genStatOct = statOct; ind++; frame = (T_P_L2R_FRAME)((UBYTE*)frame + data_ind->data_size + HT_LEN); off = 0; break; case SO_END_EMPTY: if (off EQ 0) { (*emptyfr)++; } /* fall through!!! */ case SO_BREAK_ACK: case SO_END_FULL: genStatOct = statOct; ind++; frame = (T_P_L2R_FRAME)((UBYTE*)frame + data_ind->data_size + HT_LEN); off = 0; break; case SO_TWO_OCTET: genStatOct = statOct; off += ((*frame)[off] & SO_ADR_MASK_TWO_OCT) + 2; if (off >= data_ind->data_size) { ind++; frame = (T_P_L2R_FRAME)((UBYTE*)frame + data_ind->data_size + HT_LEN); off = 0; } break; default: genStatOct = statOct; off += (statOct & SO_ADR_MASK) + 1; if (off >= data_ind->data_size) { ind++; frame = (T_P_L2R_FRAME)((UBYTE*)frame + data_ind->data_size + HT_LEN); off = 0; } break; } } if (*found) { *sa = GET_SO_SA_BIT(brkStatOct); *sb = GET_SO_SB_BIT(brkStatOct); } else { *sa = GET_SO_SA_BIT(genStatOct); *sb = GET_SO_SB_BIT(genStatOct); } if (l2r_data->dn.FlowCtrlUsed) { if (GET_SO_X_BIT (brkStatOct) EQ 0) { *flow_brk = FL_INACTIVE; } else { *flow_brk = FL_ACTIVE; } if (GET_SO_X_BIT (genStatOct) EQ 0) { *flow_gen = FL_INACTIVE; } else { *flow_gen = FL_ACTIVE; } } else { *flow_brk = FL_INACTIVE; *flow_gen = FL_INACTIVE; } } /* +------------------------------------------------------------------------------ | Function : dn_free_prim +------------------------------------------------------------------------------ | Description : | | Parameters : primDesc - | | | Return : +------------------------------------------------------------------------------ */ LOCAL void dn_free_prim(T_P_DPRIM_DESCRIPTOR primDesc) { TRACE_FUNCTION ("dn_free_prim()"); if (primDesc->prim NEQ NULL) { PFREE (primDesc->prim); primDesc->prim = NULL; primDesc->nFr = 0; primDesc->index = 0; primDesc->offset = 0; primDesc->off_status = 0; } } /* +------------------------------------------------------------------------------ | Function : dn_free_all_prims +------------------------------------------------------------------------------ | Description : frees all primititives | | Parameters : - | | | Return : - +------------------------------------------------------------------------------ */ GLOBAL void dn_free_all_prims(void) { T_DN *ddn = &l2r_data->dn; T_PRIM_DESC_RIBU_INDEX n; TRACE_FUNCTION ("dn_free_all_prims()"); for (n = 0; n < ddn->RiBu.idx.depth; n++) { dn_free_prim (ddn->RiBu._primDesc[n]); } } /* +------------------------------------------------------------------------------ | Function : dn_cond_free_prims +------------------------------------------------------------------------------ | Description : frees all primitive if r | | Parameters : - | | | Return : - +------------------------------------------------------------------------------ */ GLOBAL void dn_cond_free_prims(void) { T_DN *ddn = &l2r_data->dn; TRACE_FUNCTION ("dn_cond_free_prims()"); while (ddn->RiBu.free NEQ ddn->RiBu.idx.ri) { dn_free_prim (ddn->RiBu._primDesc[ddn->RiBu.free]); ddn->RiBu.free++; if (ddn->RiBu.free EQ ddn->RiBu.idx.depth) { ddn->RiBu.free = 0; } } } /* +------------------------------------------------------------------------------ | Function : dn_store_prim +------------------------------------------------------------------------------ | Description : | | Parameters : data_ind - | index - | | Return : - +------------------------------------------------------------------------------ */ GLOBAL void dn_store_prim(T_P_RLP_DATA_IND data_ind, T_PRIM_INDEX index) { T_DN *ddn = &l2r_data->dn; T_PRIM_INDEX m; T_P_DPRIM_DESCRIPTOR primDesc; T_PRIM_INDEX frames = data_ind->sdu.l_buf / (8 * data_ind->data_size + HT_LEN); UBYTE *pos = data_ind->sdu.buf + (data_ind->sdu.o_buf>>3) + HEADER_LEN; TRACE_FUNCTION ("dn_store_prim()"); primDesc = ddn->RiBu._primDesc[cl_ribu_write_index(&ddn->RiBu.idx)]; primDesc->prim = data_ind; primDesc->index = index; /* if BREAK then not equal 0 */ primDesc->offset = 0; primDesc->off_status = 0; primDesc->nFr = frames; for (m = 0; m < frames; m++) { (*primDesc->dadr)[m] = (T_P_L2R_FRAME)(pos + m * (data_ind->data_size + HT_LEN)); } dn_check_flow(); if (GET_STATE (DN_UL) EQ IW_WAIT AND ddn->ULFlow EQ FL_INACTIVE AND ddn->DtiConnected) /*jk: data send only when DTI connected*/ { dn_send_data_ind(); SET_STATE (DN_UL, IW_IDLE); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : L2R_DNF | | STATE : code ROUTINE : dn_init_ribu | +--------------------------------------------------------------------+ PURPOSE : */ GLOBAL void dn_init_ribu(void) { T_DN *ddn = &l2r_data->dn; T_PRIM_DESC_RIBU_INDEX n; T_PRIM_INDEX m; TRACE_FUNCTION ("dn_init_ribu()"); cl_ribu_init(&ddn->RiBu.idx, ddn->RiBu.idx.depth); ddn->RiBu.free = 0; for (n = 0; n < ddn->RiBu.idx.depth; n++) { ddn->RiBu._primDesc[n] = &(ddn->PrimDesc[n]); ddn->PrimDesc[n].nFr = 0; ddn->PrimDesc[n].dadr = (T_P_ADR_VECTOR)&(ddn->AdrVec[n]); /* dn_init_ribu */ ddn->PrimDesc[n].index = 0; ddn->PrimDesc[n].offset = 0; ddn->PrimDesc[n].off_status = 0; ddn->PrimDesc[n].prim = NULL; for (m = 0; m < L2R_FRAMES_PER_PRIM_MAX; m++) { ddn->AdrVec[n][m] = NULL; } } } /* +------------------------------------------------------------------------------ | Function : dn_cond_req_data +------------------------------------------------------------------------------ | Description : | | Parameters : - | | | Return : - +------------------------------------------------------------------------------ */ GLOBAL void dn_cond_req_data(void) { T_DN *ddn = &l2r_data->dn; TRACE_FUNCTION ("dn_cond_req_data()"); /* ring buffer full? */ if ((ddn->RiBu.idx.wi + 1) % ddn->RiBu.idx.depth EQ ddn->RiBu.free) { SET_STATE (DN_LL, IW_IDLE); } else { PALLOC (rlp_getdata_req, RLP_GETDATA_REQ); PSENDX (RLP, rlp_getdata_req); SET_STATE (DN_LL, IW_WAIT); } } /* +------------------------------------------------------------------------------ | Function : dn_store_status +------------------------------------------------------------------------------ | Description : | | Parameters : flow - | | | Return : - +------------------------------------------------------------------------------ */ GLOBAL void dn_store_status(T_FLOW flow) { T_DN *ddn = &l2r_data->dn; TRACE_FUNCTION ("dn_store_status()"); if (flow EQ ddn->LLFlow) { return; } ddn->LLFlow = flow; dn_merge_flow(); sig_dn_up_ll_flow(ddn->LLFlow); } /* +------------------------------------------------------------------------------ | Function : dn_merge_flow +------------------------------------------------------------------------------ | Description : | | Parameters : - | | | Return : - +------------------------------------------------------------------------------ */ GLOBAL void dn_merge_flow(void) { T_DN *ddn = &l2r_data->dn; TRACE_FUNCTION ("dn_merge_flow()"); if (ddn->FlowCtrlUsed AND (ddn->UpFlow EQ FL_ACTIVE OR ddn->LLFlow EQ FL_ACTIVE) ) { if (ddn->MrgFlow EQ FL_INACTIVE) { ddn->ReportMrgFlow = TRUE; /* TRACE_EVENT("DN: Merged flow set active"); */ } ddn->MrgFlow = FL_ACTIVE; } else { if (ddn->MrgFlow EQ FL_ACTIVE) { ddn->ReportMrgFlow = TRUE; /* TRACE_EVENT("DN: Merged flow set inactive"); */ } ddn->MrgFlow = FL_INACTIVE; } } /* +------------------------------------------------------------------------------ | Function : dn_cond_report_status +------------------------------------------------------------------------------ | Description : | | Parameters : - | | | Return : - +------------------------------------------------------------------------------ */ GLOBAL void dn_cond_report_status(void) { TRACE_FUNCTION ("dn_cond_report_status()"); if (l2r_data->dn.ReportMrgFlow AND GET_STATE (DN_UL) EQ IW_WAIT) { if (l2r_data->dn.DtiConnected) /*jk: data send only when DTI connected*/ { dn_send_data_ind(); SET_STATE (DN_UL, IW_IDLE); } } }