FreeCalypso > hg > fc-tourmaline
view src/g23m-aci/uart/uart_rxp.c @ 304:58c7961bd0b0 default tip
TCH tap: extend DL sniffing feature to support CSD modes
Our debug feature for TCH DL sniffing reads the content of the DSP's
a_dd_0 buffer (or a_dd_1 for TCH/H subchannel 1) at appropriate times
and forwards captured bits to the host. This feature was originally
implemented for TCH/FS, TCH/EFS and TCH/HS - now extend it to cover
TCH/F data modes too.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 25 Nov 2024 23:33:27 +0000 |
parents | fa8dc04885d8 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : | Modul : +----------------------------------------------------------------------------- | 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 UART and implements all | functions to handles the incoming primitives as described in | the SDL-documentation (RX-statemachine) +----------------------------------------------------------------------------- */ #ifndef UART_RXP_C #define UART_RXP_C #endif /* !UART_RXP_C */ #define ENTITY_UART #ifndef FF_MULTI_PORT /*==== INCLUDES =============================================================*/ #ifdef WIN32 #include "nucleus.h" #endif /* WIN32 */ #include "typedefs.h" /* to get Condat data types */ #include "vsi.h" /* to get a lot of macros */ #include "macdef.h" /* to get a lot of macros */ #include "custom.h" #include "gsm.h" /* to get a lot of macros */ #include "cnf_uart.h" /* to get cnf-definitions */ #include "mon_uart.h" /* to get mon-definitions */ #include "prim.h" /* to get the definitions of used SAP and directions */ #include "dti.h" /* to get dti lib */ #include "pei.h" /* to get PEI interfac */ #ifdef _TARGET_ #include "uart/serialswitch.h" #include "uart/traceswitch.h" #else /* _TARGET_ */ #include "serial_dat.h" /* to get definitions of serial driver */ #endif /* _TARGET_ */ #include "uart.h" /* to get the global entity definitions */ #include "uart_rxf.h" /* to get rx functions */ #include "uart_kers.h" /* to get ker signals */ #include "uart_dtxs.h" /* to get dtx signals */ #ifdef _SIMULATION_ #include <stdio.h> /* to get sprintf */ #include "uart_rxp.h" /* to get rx_readdata */ #endif /* _SIMULATION_ */ /*==== CONST ================================================================*/ /*==== LOCAL VARS ===========================================================*/ /*==== PRIVATE FUNCTIONS ====================================================*/ /*==== PUBLIC FUNCTIONS =====================================================*/ /* +------------------------------------------------------------------------------ | Function : rx_uart_driver_received_ind +------------------------------------------------------------------------------ | Description : Handles the primitive UART_DRIVER_RECEIVED_IND | | Parameters : *uart_device - affected device database | +------------------------------------------------------------------------------ */ GLOBAL void rx_uart_driver_received_ind ( T_UART_DATA* uart_device ) { USHORT i; BOOL continuous; T_DLC* dlc; T_desc2* temp_desc = NULL; ULONG line_states; TRACE_EVENT( "rx_uart_driver_received_ind()" ); /* * set affected instance */ uart_data = uart_device; /* * inform about new line states */ if(uart_data->rx.lines NEQ uart_data->rx.prev_lines) { /* * convert line states and send it */ line_states = 0; if(uart_data->rx.lines & X_MASK) { line_states|= UART_X_RX_MASK; if(!(uart_data->rx.prev_lines & X_MASK)) { TRACE_EVENT("RX Flow Control: stop"); } } else if(uart_data->rx.prev_lines & X_MASK) { TRACE_EVENT("RX Flow Control: start"); } if(uart_data->rx.lines & SA_MASK) { line_states|= UART_SA_RX_MASK; if(!(uart_data->rx.prev_lines & SA_MASK)) { TRACE_EVENT("DTR: drop"); } } else if(uart_data->rx.prev_lines & SA_MASK) { TRACE_EVENT("DTR: on"); } if(uart_data->rx.lines & SB_MASK) { line_states|= UART_SB_RX_MASK; if(!(uart_data->rx.prev_lines & SB_MASK)) { TRACE_EVENT("RTS: off"); } } else if(uart_data->rx.prev_lines & SB_MASK) { TRACE_EVENT("RTS: on"); } if(uart_data->rx.lines & ESC_MASK) { line_states|= UART_ESC_RX_MASK; TRACE_EVENT("Escape Sequence detected"); } if(uart_data->rx.lines & BRK_MASK) { line_states|= UART_BRK_RX_MASK; line_states|= (((uart_data->rx.lines & BRK_LEN_MASK) >> BRKLEN) << UART_BRKLEN_RX_POS); TRACE_EVENT("Break detected"); } /* * store new line states */ uart_data->rx.lines&= ~(ESC_MASK | BRK_MASK | BRK_LEN_MASK); uart_data->rx.prev_lines = uart_data->rx.lines; /* * inform MMI */ sig_rx_ker_line_states_ind(line_states); } switch( GET_STATE( UART_SERVICE_RX ) ) { case RX_READY: dlc = &uart_data->dlc_table[UART_CONTROL_INSTANCE]; if(uart_data->rx.dlc_instance NEQ UART_EMPTY_INSTANCE) { uart_data->rx.dlc_instance = UART_EMPTY_INSTANCE; uart_data->rx.analyze_state = UART_RX_ERROR; /* * if ISR has read out some data * inform all channels about data reception */ if(uart_data->rx.read_permission) { for(i = 0; i <= UART_MAX_NUMBER_OF_CHANNELS; i++) { switch(uart_data->dlc_table[i].receive_process) { case UART_RX_PROCESS_READY: case UART_RX_PROCESS_COMPLETE: /* * inform all channels about data reception */ uart_data->dlc_table[i].receive_process = UART_RX_PROCESS_STOP; temp_desc = uart_data->dlc_table[i].receive_data; uart_data->dlc_table[i].receive_data = NULL; if(i EQ UART_CONTROL_INSTANCE) { /* * Control channel */ sig_rx_ker_data_received_ind( temp_desc, uart_data->dlc_table[i].receive_pos); } else { /* * Data channel */ uart_data->dtx = uart_data->dlc_table[i].dtx; sig_rx_dtx_data_received_ind( temp_desc, uart_data->dlc_table[i].receive_pos); } /* fall through */ case UART_RX_PROCESS_STOP: /* * add new channels which want to receive */ if(uart_data->dlc_table[i].receive_data) uart_data->dlc_table[i].receive_process = UART_RX_PROCESS_READY; break; default: TRACE_EVENT_P2("Unexpected DLC process state: %d | uart_rxp.c(%d)", dlc->receive_process, __LINE__); break; } } } } else { switch(dlc->receive_process) { case UART_RX_PROCESS_READY: case UART_RX_PROCESS_COMPLETE: /* * if ISR has read out some data * inform channel about data reception */ if(uart_data->rx.read_permission) { /* * inform channel about data reception */ dlc->receive_process = UART_RX_PROCESS_STOP; temp_desc = dlc->receive_data; dlc->receive_data = NULL; uart_data->dtx = dlc->dtx; sig_rx_dtx_data_received_ind(temp_desc, dlc->receive_pos); } /* fall through */ case UART_RX_PROCESS_STOP: /* * add new channel which want to receive */ if(dlc->receive_data) dlc->receive_process = UART_RX_PROCESS_READY; break; default: TRACE_EVENT_P2("Unexpected DLC process state: %d | uart_rxp.c(%d)", dlc->receive_process, __LINE__); break; } } if(dlc->receive_process EQ UART_RX_PROCESS_STOP) { uart_data->rx.receive_state = UART_RX_NOT_RECEIVING; break; } #ifdef _SIMULATION_ if(rx_inpavail(uart_data->device) > 0) #else /* _SIMULATION_ */ if(UF_InpAvail (uart_data->device) > 0) #endif /* _SIMULATION_ */ { /* * inform channel about reading */ uart_data->rx.read_permission = TRUE; uart_data->dtx = dlc->dtx; sig_rx_dtx_receiving_ind(); } else uart_data->rx.read_permission = FALSE; if(uart_data EQ (&(uart_data_base[0]))) { TRACE_EVENT("UF_ReadData()"); #ifdef _SIMULATION_ rx_readdata(0); #else /* _SIMULATION_ */ UF_ReadData (uart_data->device, sm_suspend, rx_readOutFunc_0); #endif /* else _SIMULATION_ */ } #ifdef FF_TWO_UART_PORTS else if(uart_data EQ (&(uart_data_base[1]))) { TRACE_EVENT("UF_ReadData()"); #ifdef _SIMULATION_ rx_readdata(1); #else /* _SIMULATION_ */ UF_ReadData (uart_data->device, sm_suspend, rx_readOutFunc_1); #endif /* else _SIMULATION_ */ } #endif /* FF_TWO_UART_PORTS */ else { TRACE_ERROR("wrong value of uart_data"); } break; case RX_MUX: if(uart_data->rx.dlc_instance EQ UART_EMPTY_INSTANCE) { uart_data->rx.dlc_instance = UART_CONTROL_INSTANCE; uart_data->rx.analyze_state = UART_RX_ERROR; } continuous = FALSE; for(i = 0; i <= UART_MAX_NUMBER_OF_CHANNELS; i++) { dlc = &uart_data->dlc_table[i]; switch(dlc->receive_process) { case UART_RX_PROCESS_READY: case UART_RX_PROCESS_COMPLETE: /* * if ISR has read out some data * inform all channels about data reception */ if(uart_data->rx.read_permission) { dlc->receive_process = UART_RX_PROCESS_STOP; temp_desc = dlc->receive_data; dlc->receive_data = NULL; if(i EQ UART_CONTROL_INSTANCE) { /* * Control channel */ sig_rx_ker_data_received_ind(temp_desc, dlc->receive_pos); } else { /* * Data channel */ uart_data->dtx = dlc->dtx; sig_rx_dtx_data_received_ind(temp_desc, dlc->receive_pos); } } /* fall through */ case UART_RX_PROCESS_STOP: /* * add new channels which want to receive */ if(dlc->receive_data) dlc->receive_process = UART_RX_PROCESS_READY; break; default: TRACE_EVENT_P2("Unexpected DLC process state: %d, uart_rxp.c(%d)", dlc->receive_process, __LINE__); break; } if(dlc->receive_process NEQ UART_RX_PROCESS_STOP) continuous = TRUE; } /* * check whether there is a channel to receive */ if(continuous NEQ TRUE) { uart_data->rx.receive_state = UART_RX_NOT_RECEIVING; break; } #ifdef _SIMULATION_ if(rx_inpavail(uart_data->device) > 0) #else /* _SIMULATION_ */ if(UF_InpAvail (uart_data->device) > 0) #endif /* _SIMULATION_ */ { /* * inform each channel about reading */ uart_data->rx.read_permission = TRUE; for(i = 0; i <= UART_MAX_NUMBER_OF_CHANNELS; i++) { if(uart_data->dlc_table[i].receive_process EQ UART_RX_PROCESS_READY) { if(i EQ UART_CONTROL_INSTANCE) { /* * Control channel */ sig_rx_ker_receiving_ind(); } else { /* * Data channel */ uart_data->dtx = uart_data->dlc_table[i].dtx; sig_rx_dtx_receiving_ind(); } } } } else uart_data->rx.read_permission = FALSE; if(uart_data EQ (&(uart_data_base[0]))) { TRACE_EVENT("UF_ReadData()"); #ifdef _SIMULATION_ rx_readdata(0); #else /* _SIMULATION_ */ UF_ReadData (uart_data->device, sm_suspend, rx_readOutFunc_0); #endif /* else _SIMULATION_ */ } #ifdef FF_TWO_UART_PORTS else if(uart_data EQ (&(uart_data_base[1]))) { TRACE_EVENT("UF_ReadData()"); #ifdef _SIMULATION_ rx_readdata(1); #else /* _SIMULATION_ */ UF_ReadData (uart_data->device, sm_suspend, rx_readOutFunc_1); #endif /* else _SIMULATION_ */ } #endif /* FF_TWO_UART_PORTS */ else { TRACE_ERROR("wrong value of uart_data"); } break; default: TRACE_ERROR( "UART_DRIVER_RECEIVED_IND unexpected" ); break; } } /* rx_uart_driver_received_ind() */ #ifdef _SIMULATION_ /* +------------------------------------------------------------------------------ | Function : rx_dti_data_test_ind +------------------------------------------------------------------------------ | Description : Handles the primitive DTI_DATA_TEST_IND | | Parameters : *dti_data_test_ind - Ptr to primitive payload | +------------------------------------------------------------------------------ */ GLOBAL void rx_dti_data_test_ind ( T_DTI2_DATA_TEST_IND *dti_data_test_ind ) { char buf[100]; T_reInstMode reInstall; USHORT size[2]; USHORT pos; USHORT i; T_UART_DATA* uart_device; TRACE_FUNCTION( "rx_dti_data_test_ind" ); /* * set UART instance */ uart_device = &(uart_data_base[UART_TEST_C_ID_1]); /* * copy data to simulation buffer */ MFREE_DESC2(uart_device->rx.sim_buffer); MALLOC(uart_device->rx.sim_buffer, (USHORT)(sizeof(T_desc2) - 1 + (dti_data_test_ind->sdu.l_buf >> 3))); memcpy(uart_device->rx.sim_buffer->buffer, &dti_data_test_ind->sdu.buf[dti_data_test_ind->sdu.o_buf >> 3], dti_data_test_ind->sdu.l_buf >> 3); uart_device->rx.sim_buffer->len = dti_data_test_ind->sdu.l_buf >> 3; uart_device->rx.sim_buffer->next = (ULONG)NULL; uart_device->rx.sim_pos = 0; /* * trace output */ sprintf(buf, "UART device %d:", dti_data_test_ind->link_id); TRACE_FUNCTION( buf ); i = 0; pos = uart_device->rx.sim_pos; while(pos < uart_device->rx.sim_buffer->len) { i+= sprintf(&buf[i], "0x%02x, ", uart_device->rx.sim_buffer->buffer[pos]); pos++; if(i > 80) { TRACE_FUNCTION( buf ); i = 0; } else if(pos >= uart_device->rx.sim_buffer->len) { TRACE_FUNCTION( buf ); } } /* * set values for ISR */ uart_device->rx.source[0] = &uart_device->rx.sim_buffer->buffer[ uart_device->rx.sim_pos]; uart_device->rx.source[1] = NULL; size[0] = uart_device->rx.sim_buffer->len - uart_device->rx.sim_pos; size[1] = 0; /* * call actual function */ rx_readOutFunc_0 (FALSE, &reInstall, 1, uart_device->rx.source, size, 0); /* * store return values */ if(size[0] EQ 0) { MFREE_DESC2(uart_device->rx.sim_buffer); uart_device->rx.sim_buffer = NULL; } else uart_device->rx.sim_pos = uart_device->rx.sim_buffer->len - size[0]; /* * free the primitive */ PFREE(dti_data_test_ind); } /* rx_dti_data_test_ind() */ /* +------------------------------------------------------------------------------ | Function : rx_readdata +------------------------------------------------------------------------------ | Description : Simulates a UF_ReadData() call. | | Parameters : caller - calling UART instance | +------------------------------------------------------------------------------ */ GLOBAL void rx_readdata (UBYTE caller) { T_reInstMode reInstall; USHORT size[2]; T_UART_DATA* uart_device; TRACE_FUNCTION( "rx_readdata" ); /* * set UART instance */ uart_device = &(uart_data_base[caller]); if(uart_device->rx.sim_buffer EQ NULL) { /* * send DTI_GETDATA_REQ */ PALLOC (dti_getdata_req, DTI2_GETDATA_REQ); dti_getdata_req->link_id = LINK_READDATA_PORT_1; /* for usual read_data */ PSEND (hCommMMI, dti_getdata_req); } else { /* * set values for ISR */ uart_device->rx.source[0] = NULL; uart_device->rx.source[1] = &uart_device->rx.sim_buffer->buffer[ uart_device->rx.sim_pos]; size[0] = 0; size[1] = uart_device->rx.sim_buffer->len - uart_device->rx.sim_pos; /* * call actual function */ if(caller EQ 0) { rx_readOutFunc_0 (FALSE, &reInstall, 2, uart_device->rx.source, size, 0); } #ifdef FF_TWO_UART_PORTS else if(caller EQ 1) { rx_readOutFunc_1 (FALSE, &reInstall, 2, uart_device->rx.source, size, 0); } #endif /* FF_TWO_UART_PORTS */ else { TRACE_ERROR("wrong caller value"); } /* * store return values */ if(size[1] EQ 0) { MFREE_DESC2(uart_device->rx.sim_buffer); uart_device->rx.sim_buffer = NULL; } else uart_device->rx.sim_pos = uart_device->rx.sim_buffer->len - size[1]; } } /* rx_readdata() */ /* +------------------------------------------------------------------------------ | Function : rx_inpavail +------------------------------------------------------------------------------ | Description : Simulates a UF_InpAvail() call. | | Parameters : caller - calling UART instance | | Return : number of octets in Input Queue | +------------------------------------------------------------------------------ */ GLOBAL USHORT rx_inpavail (UBYTE caller) { T_UART_DATA* uart_device; TRACE_FUNCTION( "rx_inpavail" ); /* * set UART instance */ uart_device = &(uart_data_base[caller]); if(uart_device->rx.sim_buffer) return uart_device->rx.sim_buffer->len - uart_device->rx.sim_pos; else return 0; } /* rx_inpavail() */ #endif /* _SIMULATION_ */ #endif /* !FF_MULTI_PORT */