FreeCalypso > hg > fc-magnetite
view src/g23m-aci/uart/uart_dtxs.c @ 336:be011556e71f
FCHG: API implementation started
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 14 Dec 2017 21:01:59 +0000 |
parents | 53929b40109c |
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 process internal signals as | described in the SDL-documentation (DTX-statemachine) +----------------------------------------------------------------------------- */ #ifndef UART_DTXS_C #define UART_DTXS_C #endif /* !UART_DTXS_C */ #define ENTITY_UART /*==== INCLUDES =============================================================*/ #ifdef _SIMULATION_ #include <stdio.h> #endif #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 interface */ #ifdef FF_MULTI_PORT #include "gsi.h" /* to get definitions of serial driver */ #else /* FF_MULTI_PORT */ #ifdef _TARGET_ #include "uart/serialswitch.h" #include "uart/traceswitch.h" #else /* _TARGET_ */ #include "serial_dat.h" /* to get definitions of serial driver */ #endif /* _TARGET_ */ #endif /* FF_MULTI_PORT */ #include "uart.h" /* to get the global entity definitions */ #include "uart_dtxf.h" /* to get DTX function definitions */ #include "uart_dtxp.h" /* to get DTX primitive definitions */ #include "uart_kers.h" /* to get KER signal definitions */ #include "uart_rts.h" /* to get RT signal definitions */ #ifdef FF_MULTI_PORT #include "uart_prxs.h" /* to get signal definitions for service TX */ #else /* FF_MULTI_PORT */ #include "uart_rxs.h" /* to get TX signal definitions */ #endif /* FF_MULTI_PORT */ #include <string.h> /* JK, delete warnings: to get memmove, memcpy */ /*==== CONST ================================================================*/ /*==== LOCAL VARS ===========================================================*/ /*==== PRIVATE FUNCTIONS ====================================================*/ /*==== PUBLIC FUNCTIONS =====================================================*/ /* +------------------------------------------------------------------------------ | Function : sig_ker_dtx_ready_mode_req +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_KER_DTX_READY_MODE_REQ | | Parameters : dlc_instance - dlc instance wich belongs to this DTX instance | +------------------------------------------------------------------------------ */ GLOBAL void sig_ker_dtx_ready_mode_req (UBYTE dlc_instance) { TRACE_ISIG( "sig_ker_dtx_ready_mode_req" ); uart_data->dtx->dlc_instance = dlc_instance; switch( GET_STATE( UART_SERVICE_DTX ) ) { case DTX_DEAD: SET_STATE( UART_SERVICE_DTX, DTX_NOT_READY ); /* * reset line states */ uart_data->dtx->st_flow = DTI_FLOW_ON; uart_data->dtx->st_line_sa = DTI_SA_ON; uart_data->dtx->st_line_sb = DTI_SB_ON; uart_data->dtx->st_break_len = DTI_BREAK_OFF; uart_data->dtx->detect_escape = TRUE; uart_data->dtx->data_flow = UART_FLOW_ENABLED; if(uart_data->dtx->receiving_state EQ UART_DTX_NOT_RECEIVING) { /* * reset escape sequence detection */ dtx_set_esd_state( UART_ESD_NULL ); uart_data->dtx->detect_escape = TRUE; if(vsi_t_time (VSI_CALLER &(uart_data->dtx->esd_guard_time)) NEQ VSI_OK) { TRACE_ERROR_P1("VSI entity: Can't restart timer, uart_dtxs.c(%d)", __LINE__); } uart_data->dtx->esd_pos = 0; /* * start reception */ dtx_allocate_resources(); sig_dtx_rx_ready_to_receive_req( uart_data->dtx->dlc_instance, uart_data->dtx->to_send_data, uart_data->dtx->write_pos, uart_data->dtx->cur_desc_size ); } break; case DTX_READY: case DTX_NOT_READY: break; default: TRACE_ERROR( "SIG_KER_DTX_READY_MODE_REQ unexpected" ); break; } } /* sig_ker_dtx_ready_mode_req() */ /* +------------------------------------------------------------------------------ | Function : sig_ker_dtx_dead_mode_req +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_KER_DTX_DEAD_MODE_REQ | | Parameters : none | +------------------------------------------------------------------------------ */ GLOBAL void sig_ker_dtx_dead_mode_req () { TRACE_ISIG( "sig_ker_dtx_dead_mode_req" ); switch( GET_STATE( UART_SERVICE_DTX ) ) { case DTX_READY: case DTX_NOT_READY: SET_STATE( UART_SERVICE_DTX, DTX_DEAD ); /* * reset hComm_DTX_UPLINK and size_multiplier */ uart_data->dtx->dti_dtx_state = DTI_CLOSED; uart_data->dtx->size_multiplier = 3; if(uart_data->dtx->receiving_state EQ UART_DTX_NOT_RECEIVING) { /* * free recources and stop receiving */ sig_dtx_rx_not_ready_to_receive_req(uart_data->dtx->dlc_instance); dtx_free_resources(); } else uart_data->dtx->receiving_state = UART_DTX_INVALID; break; case DTX_DEAD: break; default: TRACE_ERROR( "SIG_KER_DTX_DEAD_MODE_REQ unexpected" ); break; } } /* sig_ker_dtx_dead_mode_req() */ /* +------------------------------------------------------------------------------ | Function : sig_rx_dtx_receiving_ind +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_RX_DTX_RECEIVING_IND | | Parameters : none | +------------------------------------------------------------------------------ */ GLOBAL void sig_rx_dtx_receiving_ind () { TRACE_ISIG( "sig_rx_dtx_receiving_ind" ); uart_data->dtx->receiving_state = UART_DTX_RECEIVING; switch( GET_STATE( UART_SERVICE_DTX ) ) { case DTX_READY: case DTX_NOT_READY: break; default: TRACE_ERROR( "SIG_RX_DTX_RECEIVING_IND unexpected" ); break; } } /* sig_ker_dtx_receiving_ind() */ /* +------------------------------------------------------------------------------ | Function : sig_rx_dtx_data_received_ind +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_RX_DTX_DATA_RECEIVED_IND | | Parameters : none | +------------------------------------------------------------------------------ */ GLOBAL void sig_rx_dtx_data_received_ind (T_desc2* received_data, USHORT write_pos) { T_DATA_FLOW_STATE old_data_flow; T_desc2* temp_desc; USHORT esd_pos; T_TIME cur_time; TRACE_ISIG( "sig_rx_dtx_data_received_ind" ); #ifdef UART_RANGE_CHECK if(received_data EQ NULL) { TRACE_EVENT("ERROR: received_data is NULL"); } else if((*((ULONG*)((UBYTE*)received_data - 8))) NEQ 0) { TRACE_EVENT_P1("ERROR: received_data=%08x is not allocated", received_data); } if(uart_data->dtx->to_send_data NEQ received_data) { TRACE_EVENT_P2("ERROR: to_send_data=%08x NEQ received_data=%08x", uart_data->dtx->to_send_data, received_data); } if(uart_data->dtx->to_send_data->len > uart_data->dtx->cur_desc_size) { TRACE_EVENT_P2("ERROR: to_send_data->len=%d > cur_desc_size=%d", uart_data->dtx->to_send_data->len, uart_data->dtx->cur_desc_size); } if(write_pos > uart_data->dtx->cur_desc_size) { TRACE_EVENT_P2("ERROR: write_pos=%d > cur_desc_size=%d", write_pos, uart_data->dtx->cur_desc_size); } if(uart_data->dtx->to_send_data->len > write_pos) { TRACE_EVENT_P2("ERROR: to_send_data->len=%d > write_pos=%d", uart_data->dtx->to_send_data->len, write_pos); } if(uart_data->dtx->esd_pos > write_pos) { TRACE_EVENT_P2("ERROR: esd_pos=%d > write_pos=%d", uart_data->dtx->esd_pos, write_pos); } switch(dtx_get_esd_state()) { case UART_ESD_DETECTED: if(uart_data->dtx->esd_pos < 3) { TRACE_EVENT_P1("ERROR: esd_pos=%d < 3 in UART_ESD_DETECTED state", uart_data->dtx->esd_pos); } break; case UART_ESD_CHAR_1: if(uart_data->dtx->esd_pos < 1) { TRACE_EVENT_P1("ERROR: esd_pos=%d < 1 in UART_ESD_CHAR_1 state", uart_data->dtx->esd_pos); } break; case UART_ESD_CHAR_2: if(uart_data->dtx->esd_pos < 2) { TRACE_EVENT_P1("ERROR: esd_pos=%d < 2 in UART_ESD_CHAR_2 state", uart_data->dtx->esd_pos); } break; case UART_ESD_CHAR_3: if(uart_data->dtx->esd_pos < 3) { TRACE_EVENT_P1("ERROR: esd_pos=%d < 3 in UART_ESD_CHAR_3 state", uart_data->dtx->esd_pos); } break; } #endif /* UART_RANGE_CHECK */ /* * store new write position, * current data_flow state and * current data descriptor */ uart_data->dtx->write_pos = write_pos; old_data_flow = uart_data->dtx->data_flow; temp_desc = received_data; /* * Introduce local variable here in order to prevent * the target compiler from doing wrong calculations ... */ esd_pos = uart_data->dtx->esd_pos; /* * escape sequence detection */ if(uart_data->dtx->receiving_state EQ UART_DTX_RECEIVING && uart_data->dtx->detect_escape EQ TRUE) { if (vsi_t_time (VSI_CALLER &cur_time) EQ VSI_OK) { switch(dtx_get_esd_state()) { case UART_ESD_DETECTED: /* * remove escape characters because escape sequence was detected */ if(uart_data->dtx->write_pos > esd_pos) { memmove(&temp_desc->buffer[esd_pos - 3], &temp_desc->buffer[esd_pos], uart_data->dtx->write_pos - esd_pos); } uart_data->dtx->write_pos-= 3; esd_pos -= 3; uart_data->dtx->esd_pos = esd_pos; dtx_set_esd_state( UART_ESD_NULL ); /* fall through */ case UART_ESD_NULL: #ifdef _SIMULATION_ TRACE_EVENT_P2("uart_data->act_gp: %d, silence: %d", uart_data->act_gp, (cur_time - uart_data->dtx->esd_guard_time)); #endif /* _SIMULATION_ */ if(esd_pos >= temp_desc->len) break; if(((cur_time - uart_data->dtx->esd_guard_time) < uart_data->act_gp) || (temp_desc-> buffer[esd_pos] NEQ uart_data->act_ec)) { /* * set new reference time and * update esd_pos */ esd_pos = temp_desc->len; uart_data->dtx->esd_pos = esd_pos; uart_data->dtx->esd_guard_time = cur_time; break; } /* * first guard period complete and * first escape character detected */ #ifdef _SIMULATION_ TRACE_EVENT("+ + + first guard period complete + + +"); #endif /* _SIMULATION_ */ dtx_set_esd_state( UART_ESD_CHAR_1 ); esd_pos++; uart_data->dtx->esd_pos = esd_pos; uart_data->dtx->esd_guard_time = cur_time; sig_dtx_rt_start_tesd_req (uart_data->act_gp); /* fall trough */ case UART_ESD_CHAR_1: if(esd_pos >= temp_desc->len) { /* * hide 1 character */ temp_desc->len = esd_pos - 1; temp_desc->size = temp_desc->len; break; } if(temp_desc-> buffer[esd_pos] NEQ uart_data->act_ec) { /* * second character is not an escape character */ dtx_set_esd_state( UART_ESD_NULL ); esd_pos = temp_desc->len; uart_data->dtx->esd_pos = esd_pos; uart_data->dtx->esd_guard_time = cur_time; break; } /* * second escape character received */ dtx_set_esd_state( UART_ESD_CHAR_2 ); esd_pos++; uart_data->dtx->esd_pos = esd_pos; /* fall trough */ case UART_ESD_CHAR_2: if(esd_pos >= temp_desc->len) { /* * hide 2 characters */ temp_desc->len = esd_pos - 2; temp_desc->size = temp_desc->len; break; } /* * set new reference time */ uart_data->dtx->esd_guard_time = cur_time; if(temp_desc-> buffer[esd_pos] NEQ uart_data->act_ec) { /* * third character is not an escape character */ dtx_set_esd_state( UART_ESD_NULL ); esd_pos = temp_desc->len; uart_data->dtx->esd_pos = esd_pos; break; } /* * third escape character received */ dtx_set_esd_state( UART_ESD_CHAR_3 ); esd_pos++; uart_data->dtx->esd_pos = esd_pos; sig_dtx_rt_start_tesd_req (uart_data->act_gp); /* fall trough */ case UART_ESD_CHAR_3: if(esd_pos >= temp_desc->len) { /* * hide 3 characters */ temp_desc->len = esd_pos - 3; temp_desc->size = temp_desc->len; break; } /* * fourth character received */ dtx_set_esd_state( UART_ESD_NULL ); esd_pos = temp_desc->len; uart_data->dtx->esd_pos = esd_pos; uart_data->dtx->esd_guard_time = cur_time; break; default: TRACE_ERROR("wrong esd state"); break; } } else { TRACE_ERROR_P1("VSI entity: Can't restart timer, uart_dtxs.c(%d)", __LINE__); } } switch( GET_STATE( UART_SERVICE_DTX ) ) { case DTX_DEAD: dtx_free_resources(); uart_data->dtx->receiving_state = UART_DTX_NOT_RECEIVING; break; case DTX_READY: /* * enable data flow if necessary */ if(old_data_flow NEQ UART_FLOW_ENABLED) { uart_data->dtx->data_flow = UART_FLOW_ENABLED; sig_dtx_ker_enable_ind(uart_data->dtx->dlc_instance); } if(uart_data->dtx->receiving_state EQ UART_DTX_RECEIVING) { /* * if data to send available or * line states changed */ if((temp_desc->len) || (uart_data->dtx->lines_changed)) { PALLOC_DESC2 (dti_data_ind, DTI2_DATA_IND); SET_STATE( UART_SERVICE_DTX, DTX_NOT_READY ); if(temp_desc->len) { /* * mark entity descriptor as invalid, since data will be forwarded */ uart_data->dtx->to_send_data = NULL; dti_data_ind->desc_list2.first = (ULONG)temp_desc; dti_data_ind->desc_list2.list_len = temp_desc->len; /* * calculate new size multiplier according to fillrate of buffer */ dtx_calculate_size_multiplier (temp_desc, old_data_flow); /* * allocate a new descriptor with size according to new size_multiplier */ dtx_allocate_resources(); /* * Check for data which has not yet been validated, i.e. because * the frame containing the data has not yet been received completely. * In this case, the not yet validated data is copied to the newly * allocated descriptor. */ if(uart_data->dtx->write_pos > temp_desc->len) { memcpy(uart_data->dtx->to_send_data->buffer, &temp_desc->buffer[temp_desc->len], uart_data->dtx->write_pos - temp_desc->len); uart_data->dtx->write_pos-= temp_desc->len; } esd_pos-= temp_desc->len; uart_data->dtx->esd_pos = esd_pos; } else { /* * just line states has been changed */ dti_data_ind->desc_list2.first = (ULONG)NULL; dti_data_ind->desc_list2.list_len = 0; } /* * set line states and * mark line states as unchanged; */ dti_data_ind->parameters.st_lines.st_flow = uart_data->dtx->st_flow; dti_data_ind->parameters.st_lines.st_line_sa = uart_data->dtx->st_line_sa; dti_data_ind->parameters.st_lines.st_line_sb = uart_data->dtx->st_line_sb; dti_data_ind->parameters.st_lines.st_break_len = uart_data->dtx->st_break_len; uart_data->dtx->lines_changed = FALSE; uart_data->dtx->st_break_len = DTI_BREAK_OFF; dti_send_data( uart_hDTI, uart_data->device, UART_DTI_UP_INTERFACE, uart_data->dtx->dlc_instance, dti_data_ind ); } } else { /* * invalid data * free recources and allocate a new descriptor because * size_multiplier may have changed */ dtx_free_resources(); dtx_allocate_resources(); /* * reset escape sequence detection */ dtx_set_esd_state( UART_ESD_NULL ); if(vsi_t_time (VSI_CALLER &(uart_data->dtx->esd_guard_time)) NEQ VSI_OK) { TRACE_ERROR_P1("VSI entity: Can't restart timer, uart_dtxs.c(%d)", __LINE__); } esd_pos = 0; uart_data->dtx->esd_pos = esd_pos; } /* * signal availability to receive to RX service */ uart_data->dtx->receiving_state = UART_DTX_NOT_RECEIVING; sig_dtx_rx_ready_to_receive_req( uart_data->dtx->dlc_instance, uart_data->dtx->to_send_data, uart_data->dtx->write_pos, uart_data->dtx->cur_desc_size ); break; case DTX_NOT_READY: if(uart_data->dtx->receiving_state EQ UART_DTX_RECEIVING) { uart_data->dtx->receiving_state = UART_DTX_NOT_RECEIVING; if((old_data_flow NEQ UART_FLOW_DISABLED) && ((uart_data->dtx->cur_desc_size - temp_desc->len) < ((USHORT)uart_data->n1 << 1))) { /* * the service DTX is receiving but there is not enough space left * therefore it is necessary to disable the data flow */ uart_data->dtx->data_flow = UART_FLOW_DISABLED; sig_dtx_ker_disable_ind(uart_data->dtx->dlc_instance); } if((uart_data->dtx->cur_desc_size - esd_pos) >= uart_data->n1) { /* * there is still enough space left to continue reception */ sig_dtx_rx_ready_to_receive_req(uart_data->dtx->dlc_instance, uart_data->dtx->to_send_data, uart_data->dtx->write_pos, uart_data->dtx->cur_desc_size); } } else { /* * invalid data * free recources and allocate a new descriptor * because size_multiplier may have changed */ dtx_free_resources(); dtx_allocate_resources(); /* * reset escape sequence detection */ dtx_set_esd_state( UART_ESD_NULL ); if(vsi_t_time (VSI_CALLER &(uart_data->dtx->esd_guard_time)) NEQ VSI_OK) { TRACE_ERROR_P1("VSI entity: Can't restart timer, uart_dtxs.c(%d)", __LINE__); } esd_pos = 0; uart_data->dtx->esd_pos = esd_pos; /* * enable flow control if necessary */ if(old_data_flow NEQ UART_FLOW_ENABLED) { uart_data->dtx->data_flow = UART_FLOW_ENABLED; sig_dtx_ker_enable_ind(uart_data->dtx->dlc_instance); } /* * signal availability to receive to RX service */ uart_data->dtx->receiving_state = UART_DTX_NOT_RECEIVING; sig_dtx_rx_ready_to_receive_req( uart_data->dtx->dlc_instance, uart_data->dtx->to_send_data, uart_data->dtx->write_pos, uart_data->dtx->cur_desc_size ); } break; default: TRACE_ERROR( "SIG_RX_DTX_DATA_RECEIVED_IND unexpected" ); break; } } /* sig_rx_dtx_data_received_ind() */ /* +------------------------------------------------------------------------------ | Function : sig_ker_dtx_line_states_req +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_KER_DTX_LINE_STATES_REQ | which indicates that one or more line status signals have | changed | | Parameters : st_flow - flow control state (X bit) | st_line_sa - line state SA | st_line_sa - line state SB | st_break_len - break length | +------------------------------------------------------------------------------ */ GLOBAL void sig_ker_dtx_line_states_req(UBYTE st_flow, UBYTE st_line_sa, UBYTE st_line_sb, UBYTE st_break_len) { TRACE_ISIG( "sig_ker_dtx_line_states_req" ); switch( GET_STATE( UART_SERVICE_DTX ) ) { case DTX_READY: if((st_flow NEQ uart_data->dtx->st_flow) || (st_line_sa NEQ uart_data->dtx->st_line_sa) || (st_line_sb NEQ uart_data->dtx->st_line_sb) || (st_break_len NEQ uart_data->dtx->st_break_len)) { /* * send line states to DTI peer */ PALLOC_DESC2 (dti_data_ind, DTI2_DATA_IND); SET_STATE( UART_SERVICE_DTX, DTX_NOT_READY ); /* * store new line states */ uart_data->dtx->st_flow = st_flow; uart_data->dtx->st_line_sa = st_line_sa; uart_data->dtx->st_line_sb = st_line_sb; uart_data->dtx->st_break_len = st_break_len; /* * just line states has been changed */ dti_data_ind->desc_list2.first = (ULONG)NULL; dti_data_ind->desc_list2.list_len = 0; /* * set line states and * mark line states as unchanged; */ dti_data_ind->parameters.st_lines.st_flow = uart_data->dtx->st_flow; dti_data_ind->parameters.st_lines.st_line_sa = uart_data->dtx->st_line_sa; dti_data_ind->parameters.st_lines.st_line_sb = uart_data->dtx->st_line_sb; dti_data_ind->parameters.st_lines.st_line_sb = uart_data->dtx->st_line_sb; dti_data_ind->parameters.st_lines.st_break_len = uart_data->dtx->st_break_len; uart_data->dtx->lines_changed = FALSE; uart_data->dtx->st_break_len = DTI_BREAK_OFF; dti_send_data( uart_hDTI, uart_data->device, UART_DTI_UP_INTERFACE, uart_data->dtx->dlc_instance, dti_data_ind ); } break; case DTX_NOT_READY: if((st_flow NEQ uart_data->dtx->st_flow) || (st_line_sa NEQ uart_data->dtx->st_line_sa) || (st_line_sb NEQ uart_data->dtx->st_line_sb) || (st_break_len NEQ uart_data->dtx->st_break_len)) { /* * If previously break detected keep information in * uart_data->dtx->st_break_len */ if(uart_data->dtx->st_break_len EQ DTI_BREAK_OFF) uart_data->dtx->st_break_len = st_break_len; /* * store new line states */ uart_data->dtx->st_flow = st_flow; uart_data->dtx->st_line_sa = st_line_sa; uart_data->dtx->st_line_sb = st_line_sb; /* * mark line states as changed */ uart_data->dtx->lines_changed = TRUE; } break; default: TRACE_ERROR( "SIG_KER_DTX_LINE_STATES_REQ unexpected" ); break; } } /* sig_ker_dtx_line_states_req */ /* +------------------------------------------------------------------------------ | Function : sig_ker_dtx_detect_escape_req +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_KER_DTX_DETECT_ESCAPE_REQ | which enables escape sequence detection | | Parameters : detect_escape - TRUE/FALSE | +------------------------------------------------------------------------------ */ GLOBAL void sig_ker_dtx_detect_escape_req (UBYTE detect_escape) { TRACE_ISIG( "sig_ker_dtx_detect_req" ); uart_data->dtx->detect_escape = detect_escape; } /* sig_ker_dtx_detect_req() */ /* +------------------------------------------------------------------------------ | Function : sig_ker_dtx_disconnected_mode_req +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_KER_DTX_DISCONNECTED_MODE_REQ | | Parameters : none | +------------------------------------------------------------------------------ */ GLOBAL void sig_ker_dtx_disconnected_mode_req () { TRACE_ISIG( "sig_ker_dtx_disconnected_mode_req" ); uart_data->dtx->dti_dtx_state = DTI_CLOSED; switch(GET_STATE( UART_SERVICE_DTX) ) { case DTX_READY: SET_STATE( UART_SERVICE_DTX, DTX_NOT_READY ); break; case DTX_NOT_READY: break; default: TRACE_ERROR( "SIG_KER_DTX_DISCONNECTED_MODE_REQ unexpected" ); break; } } /* sig_ker_dtx_disconnected_mode_req() */ /* +------------------------------------------------------------------------------ | Function : sig_ker_dtx_set_dtilib_peer_req +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_KER_DTX_SET_DTI_PEER_REQ | which is used to inform the service DTX that from now on it | needs to communicate with a (new) peer | | Parameters : - | +------------------------------------------------------------------------------ */ GLOBAL void sig_ker_dtx_set_dtilib_peer_req () { TRACE_ISIG( "sig_ker_dtx_set_dtilib_peer_req" ); /* * set dtilib parameters */ uart_data->dtx->dti_dtx_state = DTI_IDLE; /* * reset size_multiplier */ uart_data->dtx->size_multiplier = 3; /* * switch to new DTX state depending on current state */ switch( GET_STATE( UART_SERVICE_DTX ) ) { case DTX_READY: SET_STATE( UART_SERVICE_DTX, DTX_NOT_READY ); /* fall through */ case DTX_NOT_READY: { if(uart_data->dtx->receiving_state EQ UART_DTX_NOT_RECEIVING) { /* * reset received data */ dtx_free_resources(); dtx_allocate_resources(); /* * reset escape sequence detection */ dtx_set_esd_state( UART_ESD_NULL ); if(vsi_t_time (VSI_CALLER &(uart_data->dtx->esd_guard_time)) NEQ VSI_OK) { TRACE_ERROR_P1("VSI entity: Can't restart timer, uart_dtxs.c(%d)", __LINE__); } uart_data->dtx->esd_pos = 0; /* * enable flow control if necessary */ if(uart_data->dtx->data_flow NEQ UART_FLOW_ENABLED) { uart_data->dtx->data_flow = UART_FLOW_ENABLED; sig_dtx_ker_enable_ind(uart_data->dtx->dlc_instance); } /* * signal availability to receive to RX service */ sig_dtx_rx_ready_to_receive_req( uart_data->dtx->dlc_instance, uart_data->dtx->to_send_data, uart_data->dtx->write_pos, uart_data->dtx->cur_desc_size ); } else uart_data->dtx->receiving_state = UART_DTX_INVALID; } break; case DTX_DEAD: break; default: TRACE_ERROR( "SIG_KER_DTX_SET_DTI_PEER_REQ unexpected" ); break; } } /* sig_ker_dtx_set_dtilib_peer_req() */ /* +------------------------------------------------------------------------------ | Function : sig_ker_dtx_timeout_tesd_req +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_KER_DTX_TIMEOUT_TESD_REQ | which is used to inform the service DTX that the Escape | Sequence Guard Period timer has expired. | | Parameters : none | +------------------------------------------------------------------------------ */ GLOBAL void sig_ker_dtx_timeout_tesd_req() { T_DATA_FLOW_STATE old_data_flow; T_TIME cur_time; T_TIME elapsed; T_desc2* temp_desc; TRACE_ISIG( "sig_ker_dtx_timeout_tesd_req" ); switch( GET_STATE( UART_SERVICE_DTX ) ) { case DTX_READY: if (vsi_t_time (VSI_CALLER &cur_time) EQ VSI_OK) { elapsed = cur_time - uart_data->dtx->esd_guard_time; switch (dtx_get_esd_state()) { case UART_ESD_DETECTED: case UART_ESD_NULL: break; case UART_ESD_CHAR_1: case UART_ESD_CHAR_2: if(elapsed < uart_data->act_gp) { /* * escape sequence guard period not complete: start timer * with remaining time value */ sig_dtx_rt_start_tesd_req (uart_data->act_gp - elapsed); } else { /* * Guard Period complete * reset detection because detected characters do not belong to * an escape sequence */ dtx_set_esd_state( UART_ESD_NULL ); /* * if possible send the escape character */ if(uart_data->dtx->receiving_state EQ UART_DTX_NOT_RECEIVING) { /* * Guard Period complete * send one escape character to DTI peer and reset detection */ PALLOC_DESC2 (dti_data_ind, DTI2_DATA_IND); SET_STATE( UART_SERVICE_DTX, DTX_NOT_READY ); /* * enable data flow if necessary */ old_data_flow = uart_data->dtx->data_flow; if(uart_data->dtx->data_flow NEQ UART_FLOW_ENABLED) { uart_data->dtx->data_flow = UART_FLOW_ENABLED; sig_dtx_ker_enable_ind(uart_data->dtx->dlc_instance); } /* * mark entity descriptor as invalid, since data will be * forwarded */ temp_desc = uart_data->dtx->to_send_data; uart_data->dtx->to_send_data = NULL; /* * make escape character valid to send and insert values in * primitive */ temp_desc->len = uart_data->dtx->esd_pos; temp_desc->size = temp_desc->len; dti_data_ind->desc_list2.first = (ULONG)temp_desc; dti_data_ind->desc_list2.list_len = temp_desc->len; /* * calculate new size multiplier according to fillrate of buffer */ dtx_calculate_size_multiplier (temp_desc, old_data_flow); /* * allocate a new descriptor with size according to new size_multiplier */ dtx_allocate_resources(); /* * Check for data which has not yet been validated, i.e. because * the frame containing the data has not yet been received completely. * In this case, the not yet validated data is copied to the newly * allocated descriptor. */ if(uart_data->dtx->write_pos > temp_desc->len) { memcpy(uart_data->dtx->to_send_data->buffer, &temp_desc->buffer[temp_desc->len], uart_data->dtx->write_pos - temp_desc->len); uart_data->dtx->write_pos-= temp_desc->len; } uart_data->dtx->esd_pos = 0; sig_dtx_rx_ready_to_receive_req(uart_data->dtx->dlc_instance, uart_data->dtx->to_send_data, uart_data->dtx->write_pos, uart_data->dtx->cur_desc_size); /* * set line states */ dti_data_ind->parameters.st_lines.st_flow = uart_data->dtx->st_flow; dti_data_ind->parameters.st_lines.st_line_sa = uart_data->dtx->st_line_sa; dti_data_ind->parameters.st_lines.st_line_sb = uart_data->dtx->st_line_sb; dti_data_ind->parameters.st_lines.st_break_len = uart_data->dtx->st_break_len; uart_data->dtx->lines_changed = FALSE; uart_data->dtx->st_break_len = DTI_BREAK_OFF; #ifdef _SIMULATION_ dti_data_ind->parameters.p_id = DTI_PID_UOS; #endif /* _SIMULATION_ */ dti_send_data( uart_hDTI, uart_data->device, UART_DTI_UP_INTERFACE, uart_data->dtx->dlc_instance, dti_data_ind ); } } break; case UART_ESD_CHAR_3: if(elapsed < uart_data->act_gp) { /* * escape sequence guard period not complete: start timer * with remaining time value */ sig_dtx_rt_start_tesd_req (uart_data->act_gp - elapsed); } else { /* * Guard Period complete * Escape Sequence detected */ /* * remove escape characters from data stream */ if(uart_data->dtx->receiving_state EQ UART_DTX_NOT_RECEIVING) { if(uart_data->dtx->write_pos > 3) { memmove(uart_data->dtx->to_send_data->buffer, &uart_data->dtx->to_send_data->buffer[3], uart_data->dtx->write_pos - 3) ; /*lint !e416 creation of out-of-bounds pointer */ uart_data->dtx->write_pos-= 3; } else uart_data->dtx->write_pos = 0; uart_data->dtx->esd_pos = 0; sig_dtx_rx_ready_to_receive_req(uart_data->dtx->dlc_instance, uart_data->dtx->to_send_data, uart_data->dtx->write_pos, uart_data->dtx->cur_desc_size); /* * Reset the state of the Escape Sequence Detection */ dtx_set_esd_state( UART_ESD_NULL ); } else { /* * escape characters are not removeable * so we will do this later */ #ifdef _SIMULATION_ TRACE_EVENT("ESD: escape characters are not removeable"); #endif /* _SIMULATION_ */ dtx_set_esd_state( UART_ESD_DETECTED ); } #ifdef _SIMULATION_ TRACE_EVENT_P3("+ + + dlc_instance: %d, silence %d \ (from %d) Escape Sequence Detected + + + ", uart_data->dtx->dlc_instance, elapsed, uart_data->dtx->esd_guard_time); #endif /* _SIMULATION_ */ /* * send detected escape sequence to MMI */ sig_dtx_ker_escape_detected_ind(uart_data->dtx->dlc_instance); } break; default: { TRACE_ERROR_P1("Error: wrong ESD state, uart_dtxs.c(%d)", __LINE__); } break; } } else { TRACE_ERROR_P1("VSI entity: Cannot restart timer, uart_dtxs.c(%d)", __LINE__); } break; case DTX_NOT_READY: if (vsi_t_time (VSI_CALLER &cur_time) EQ VSI_OK) { elapsed = cur_time - uart_data->dtx->esd_guard_time; switch (dtx_get_esd_state()) { case UART_ESD_DETECTED: case UART_ESD_NULL: break; case UART_ESD_CHAR_1: case UART_ESD_CHAR_2: if(elapsed < uart_data->act_gp) { /* * escape sequence guard period not complete: start timer * with remaining time value */ sig_dtx_rt_start_tesd_req (uart_data->act_gp - elapsed); } else { /* * Guard Period complete * reset detection because detected characters do not belong to * an escape sequence */ dtx_set_esd_state( UART_ESD_NULL ); /* * if possible insert escape characters to usual data stream */ if(uart_data->dtx->receiving_state EQ UART_DTX_NOT_RECEIVING) { /* * make escape character valid to send and insert values in * primitive */ uart_data->dtx->to_send_data->len = uart_data->dtx->esd_pos; uart_data->dtx->to_send_data->size = uart_data->dtx->esd_pos; uart_data->dtx->to_send_data->offset = 0; if((uart_data->dtx->cur_desc_size - uart_data->dtx->esd_pos) >= uart_data->n1) { /* * there is still enough space left to continue reception */ sig_dtx_rx_ready_to_receive_req( uart_data->dtx->dlc_instance, uart_data->dtx->to_send_data, uart_data->dtx->write_pos, uart_data->dtx->cur_desc_size); } } } break; case UART_ESD_CHAR_3: if(elapsed < uart_data->act_gp) { /* * escape sequence guard period not complete: start timer * with remaining time value */ sig_dtx_rt_start_tesd_req (uart_data->act_gp - elapsed); } else { /* * Guard Period complete * Escape Sequence detected * store the occurence of the Escape Sequence */ #ifdef _SIMULATION_ TRACE_EVENT_P3("+ + + dlc_instance: %d, silence %d \ (from %d) Escape Sequence Detected + + + ", uart_data->dtx->dlc_instance, elapsed, uart_data->dtx->esd_guard_time); #endif /* _SIMULATION_ */ /* * remove escape characters from data stream */ if(uart_data->dtx->receiving_state EQ UART_DTX_NOT_RECEIVING) { if(uart_data->dtx->write_pos > uart_data->dtx->esd_pos) { memmove( &uart_data->dtx->to_send_data->buffer[ uart_data->dtx->esd_pos - 3], &uart_data->dtx->to_send_data->buffer[ uart_data->dtx->esd_pos], uart_data->dtx->write_pos - uart_data->dtx->esd_pos); } uart_data->dtx->write_pos-= 3; uart_data->dtx->esd_pos -= 3; /* * Reset the state of the Escape Sequence Detection */ dtx_set_esd_state( UART_ESD_NULL ); if((uart_data->dtx->cur_desc_size - uart_data->dtx->esd_pos) >= uart_data->n1) { /* * there is still enough space left to continue reception */ sig_dtx_rx_ready_to_receive_req( uart_data->dtx->dlc_instance, uart_data->dtx->to_send_data, uart_data->dtx->write_pos, uart_data->dtx->cur_desc_size); } } else { /* * escape characters are not removeable * so we will do this later */ #ifdef _SIMULATION_ TRACE_EVENT("ESD: escape characters are not removeable"); #endif /* _SIMULATION_ */ dtx_set_esd_state( UART_ESD_DETECTED ); } /* * send detected escape sequence to MMI */ sig_dtx_ker_escape_detected_ind(uart_data->dtx->dlc_instance); } break; default: TRACE_ERROR("wrong esd state"); break; } } break; case DTX_DEAD: break; default: TRACE_ERROR( "SIG_KER_DTX_TIMEOUT_TESD_REQ unexpected" ); break; } } /* sig_ker_dtx_timeout_tesd_req() */