FreeCalypso > hg > fc-magnetite
view src/g23m-fad/l2r/l2r_dnf.c @ 701:35e7f9d0379f
targets: add TARGET_HAS_BUZZER to c11x, c139 and dsample
This new target config preprocessor symbol was introduced in Tourmaline
in connection with the new approach to playing buzzer melodies via PWT,
properly omitting the responsible code on targets where BU output
controls the vibrator instead. That code is not present in Magnetite
and we have no plans to backport it here, but target header files
should be kept consistent between the two trees, especially given
that we plan to support FC Venus target in Magnetite.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 26 Mar 2022 19:51:34 +0000 |
parents | 90eb61ecd093 |
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); } } }