FreeCalypso > hg > fc-magnetite
diff src/g23m-fad/ppp/ppp_frxf.c @ 174:90eb61ecd093
src/g23m-fad: initial import from TCS3.2/LoCosto
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 12 Oct 2016 05:40:46 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/g23m-fad/ppp/ppp_frxf.c Wed Oct 12 05:40:46 2016 +0000 @@ -0,0 +1,1365 @@ +/* ++----------------------------------------------------------------------------- +| 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 PPP and implements all +| procedures and functions as described in the +| SDL-documentation (FRX-statemachine) ++----------------------------------------------------------------------------- +*/ + +#define ENTITY_PPP + +/*==== INCLUDES =============================================================*/ + +#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" /* to get a lot of macros */ +/*lint -efile(766,gsm.h) */ +#include "gsm.h" /* to get a lot of macros */ +/*lint -efile(766,cnf_ppp.h) */ +#include "cnf_ppp.h" /* to get cnf-definitions */ +/*lint -efile(766,mon_ppp.h) */ +#include "mon_ppp.h" /* to get mon-definitions */ +#include "prim.h" /* to get the definitions of used SAP and directions */ +#include "dti.h" /* to get the DTILIB definitions */ +#include "ppp.h" /* to get the global entity definitions */ +#include "ppp_ptxs.h" /* to get signal interface from ptx */ + +#include "ppp_arbf.h" /* to get arb functions */ + +#include <string.h> /* to get memcpy */ + +#ifdef PPP_HDLC_TRACE +#include <stdio.h> /* to get sprintf */ +#endif /* PPP_HDLC_TRACE */ +/*==== CONST ================================================================*/ + +/*==== LOCAL VARS ===========================================================*/ + +/*==== PRIVATE FUNCTIONS ====================================================*/ + +/*==== PUBLIC FUNCTIONS =====================================================*/ + + + +#ifndef PPP_INT_RAM +/* ++------------------------------------------------------------------------------ +| Function : frx_init ++------------------------------------------------------------------------------ +| Description : The function frx_init() initializes Frame Receive (FRX) +| +| Parameters : no parameters +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void frx_init () +{ + TRACE_FUNCTION( "frx_init" ); + + ppp_data->frx.frame_complete = FALSE; + ppp_data->frx.stored_packet = NULL; + ppp_data->frx.received_data = NULL; + ppp_data->frx.store_state = FRX_ADD_ERROR; + ppp_data->frx.data_flow_state = FRX_DATA_FLOW_DEAD; + +#ifdef PPP_HDLC_TRACE + ppp_data->frx.hdlc_frame = NULL; +#endif /* PPP_HDLC_TRACE */ + + INIT_STATE( PPP_SERVICE_FRX , FRX_DEAD ); +} /* frx_init() */ +#endif /* PPP_INT_RAM */ + + +#ifndef PPP_FLASH_ROM +/* ++------------------------------------------------------------------------------ +| Function : frx_add_desc ++------------------------------------------------------------------------------ +| Description : The function frx_add_desc() appends the given +| generic data descriptor to the already received descriptors. +| The function removes transparent characters and calculates +| the fcs. +| +| Parameters : no parameters +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void frx_add_desc () +{ + UBYTE store_state; + UBYTE currentbyte; + USHORT fcs; + UBYTE escape; + USHORT s_offset; + USHORT s_size; + UBYTE* destination; + USHORT d_offset; + USHORT d_size; + USHORT* fcstab; + T_desc2* source_desc; + T_desc2* temp_desc; + USHORT packet_len; +#ifdef PPP_HDLC_TRACE + T_desc2* trace_desc; + T_desc2* trace_desc2; + T_desc2* trace_desc3; + USHORT trace_pos; + char buf[100]; + USHORT i; +#endif /* PPP_HDLC_TRACE */ + + TRACE_FUNCTION( "frx_add_desc" ); + +#ifdef PPP_HDLC_TRACE + /* + * trace HDLC frame + * the goal is to trace out only erroneous PPP frames + * if a correct PPP frame is received + * we just release the stored copy of this frame without tracing + */ + /* + * set source pointer + */ + trace_desc = ppp_data->frx.received_data; + trace_pos = ppp_data->frx.proceed_data; + switch(ppp_data->frx.store_state) + { + case FRX_ADD_ERROR: + /* + * we trace out each byte til the first HDLC flag + */ + /* + * release old stored HDLC frame + * this should not be necessary + */ + MFREE_DESC2(ppp_data->frx.hdlc_frame); + ppp_data->frx.hdlc_frame = NULL; + /* + * trace incomming data until the first HDLC flag + */ + while((trace_desc) && (trace_pos >= trace_desc->len)) + { + trace_desc = (T_desc2*)trace_desc->next; + trace_pos = 0; + } + if((trace_desc) && + (trace_desc->buffer[trace_pos] NEQ PPP_HDLC_FLAG)) + { + TRACE_EVENT("waiting for next HDLC flag:"); + i = 0; + do + { + i+= sprintf(&buf[i], "0x%02x, ", trace_desc->buffer[trace_pos]); + trace_pos++; + while((trace_desc) && (trace_pos >= trace_desc->len)) + { + trace_desc = (T_desc2*)trace_desc->next; + trace_pos = 0; + } + if(i > 80) + { + TRACE_EVENT( buf ); + i = 0; + } + } + while((trace_desc) && + (trace_desc->buffer[trace_pos] NEQ PPP_HDLC_FLAG)); + if(i > 0) + { + TRACE_EVENT( buf ); + i = 0; + } + } + break; + + case FRX_ADD_HDLC_BEGIN: + /* + * we store just the first HDLC flag and fall through + * to the default case to store the complete PPP frame + */ + /* + * release old stored HDLC frame + */ + MFREE_DESC2(ppp_data->frx.hdlc_frame); + ppp_data->frx.hdlc_frame = NULL; + + if(trace_desc) + { + /* + * allocate first descriptor to store new HDLC frame + */ + MALLOC(trace_desc2, + (USHORT)(sizeof(T_desc2) - 1 + FRX_ADD_SMALL_PACKET_SIZE)); + trace_desc2->len = 0; + trace_desc2->next = (ULONG)NULL; + ppp_data->frx.hdlc_frame = trace_desc2; + + /* + * store first HDLC flag + */ + TRACE_EVENT_P2("start flag found in desc=0x%08x: pos=%d", + trace_desc, + trace_pos); + trace_desc2->buffer[trace_desc2->len] = trace_desc->buffer[trace_pos]; + trace_desc2->len++; + trace_pos++; + while((trace_desc) && (trace_pos >= trace_desc->len)) + { + trace_desc = (T_desc2*)trace_desc->next; + trace_pos = 0; + } + } + /* fall through */ + default: + /* + * to store the complete PPP frame + */ + /* + * set destination pointer + */ + trace_desc2 = ppp_data->frx.hdlc_frame; + while(trace_desc2->next NEQ (ULONG)NULL) + { + trace_desc2 = (T_desc2*)trace_desc2->next; + } + + /* + * set source pointer + */ + while((trace_desc) && (trace_pos >= trace_desc->len)) + { + trace_desc = (T_desc2*)trace_desc->next; + trace_pos = 0; + } + + if(trace_desc) + { + /* + * store HDLC frame + */ + while((trace_desc) && + (trace_desc->buffer[trace_pos] NEQ PPP_HDLC_FLAG)) + { + if(trace_desc2->len >= FRX_ADD_SMALL_PACKET_SIZE) + { + MALLOC(trace_desc3, (USHORT)(sizeof(T_desc2) - 1 + + FRX_ADD_SMALL_PACKET_SIZE)); + trace_desc3->len = 0; + trace_desc3->next = (ULONG)NULL; + trace_desc2->next = (ULONG)trace_desc3; + trace_desc2 = trace_desc3; + } + trace_desc2->buffer[trace_desc2->len] = + trace_desc->buffer[trace_pos]; + trace_desc2->len++; + trace_pos++; + while((trace_desc) && (trace_pos >= trace_desc->len)) + { + trace_desc = (T_desc2*)trace_desc->next; + trace_pos = 0; + } + } + /* + * store last HDLC flag + */ + if(trace_desc) + { + if(trace_desc2->len >= FRX_ADD_SMALL_PACKET_SIZE) + { + MALLOC(trace_desc3, (USHORT)(sizeof(T_desc2) - 1 + + FRX_ADD_SMALL_PACKET_SIZE)); + trace_desc3->len = 0; + trace_desc3->next = (ULONG)NULL; + trace_desc2->next = (ULONG)trace_desc3; + trace_desc2 = trace_desc3; + } + TRACE_EVENT_P2("stop flag found in desc=0x%08x pos=%d", + trace_desc, + trace_pos); + trace_desc2->buffer[trace_desc2->len] = + trace_desc->buffer[trace_pos]; + trace_desc2->len++; + trace_pos++; + } + } + break; + } +#endif /* PPP_HDLC_TRACE */ + /* + * copy all important values into local variables + */ + store_state = ppp_data->frx.store_state; + fcs = ppp_data->frx.calc_fcs; + escape = ppp_data->frx.escape; + source_desc = ppp_data->frx.received_data; + s_offset = ppp_data->frx.proceed_data; + fcstab = ppp_data->fcstab; + /* + * set destination pointer + */ + destination = NULL; + d_offset = 0; + d_size = 0; + switch(store_state) + { + case FRX_ADD_INFORMATION: + case FRX_ADD_FCS1: + case FRX_ADD_FCS2: + destination = ppp_data->frx.cur_desc->buffer; + d_offset = ppp_data->frx.cur_desc->len; + d_size = ppp_data->frx.cur_desc_size; + break; + } /*lint !e744 switch statement has no default */ + /* + * while there is still data to analyze and + * a complete packet is not yet received + */ + while((source_desc) && (ppp_data->frx.frame_complete EQ FALSE)) + { + /* + * while the current descriptor is not yet complete analyzed. + * if a complete packet is analyzed we leave the loop via break command + */ + for(s_size = source_desc->len; s_offset < s_size; s_offset++) + { + /* + * set current byte + */ + currentbyte = source_desc->buffer[s_offset]; + /* + * detect HDLC flag + */ + if(currentbyte EQ PPP_HDLC_FLAG) + { + if(store_state EQ FRX_ADD_ERROR) + { +#ifdef PPP_HDLC_TRACE + /* + * store next HDLC frame + */ + /* + * release old stored HDLC frame + */ + MFREE_DESC2(ppp_data->frx.hdlc_frame); + ppp_data->frx.hdlc_frame = NULL; + /* + * set source pointer + */ + trace_desc = source_desc; + trace_pos = s_offset; + /* + * allocate first descriptor to store new HDLC frame + */ + MALLOC(trace_desc2, (USHORT)(sizeof(T_desc2) - 1 + + FRX_ADD_SMALL_PACKET_SIZE)); + trace_desc2->len = 0; + trace_desc2->next = (ULONG)NULL; + ppp_data->frx.hdlc_frame = trace_desc2; + + /* + * store first HDLC flag + */ + TRACE_EVENT_P2("start flag found in desc=0x%08x pos=%d", + trace_desc, + trace_pos); + trace_desc2->buffer[trace_desc2->len] = + trace_desc->buffer[trace_pos]; + trace_desc2->len++; + trace_pos++; + while((trace_desc) && (trace_pos >= trace_desc->len)) + { + trace_desc = (T_desc2*)trace_desc->next; + trace_pos = 0; + } + if(trace_desc) + { + /* + * store HDLC frame + */ + while((trace_desc) && + (trace_desc->buffer[trace_pos] NEQ PPP_HDLC_FLAG)) + { + if(trace_desc2->len >= FRX_ADD_SMALL_PACKET_SIZE) + { + MALLOC(trace_desc3, (USHORT)(sizeof(T_desc2) - 1 + + FRX_ADD_SMALL_PACKET_SIZE)); + trace_desc3->len = 0; + trace_desc3->next = (ULONG)NULL; + trace_desc2->next = (ULONG)trace_desc3; + trace_desc2 = trace_desc3; + } + trace_desc2->buffer[trace_desc2->len] = + trace_desc->buffer[trace_pos]; + trace_desc2->len++; + trace_pos++; + while((trace_desc) && (trace_pos >= trace_desc->len)) + { + trace_desc = (T_desc2*)trace_desc->next; + trace_pos = 0; + } + } + /* + * store last HDLC flag + */ + if(trace_desc) + { + if(trace_desc2->len >= FRX_ADD_SMALL_PACKET_SIZE) + { + MALLOC(trace_desc3, (USHORT)(sizeof(T_desc2) - 1 + + FRX_ADD_SMALL_PACKET_SIZE)); + trace_desc3->len = 0; + trace_desc3->next = (ULONG)NULL; + trace_desc2->next = (ULONG)trace_desc3; + trace_desc2 = trace_desc3; + } + TRACE_EVENT_P2("stop flag found in desc=0x%08x pos=%d", + trace_desc, + trace_pos); + trace_desc2->buffer[trace_desc2->len] = + trace_desc->buffer[trace_pos]; + trace_desc2->len++; + trace_pos++; + } + } +#endif /* PPP_HDLC_TRACE */ + store_state = FRX_ADD_HDLC_BEGIN; + } + /* + * begin of frame detected + */ + if(store_state EQ FRX_ADD_HDLC_BEGIN) + { + /* + * initialize new packet + */ + ppp_data->frx.stored_len = 0; + d_offset = 0; + ppp_data->frx.stored_ptype = 0x0000; + fcs = PPP_INITFCS; + escape = FALSE; + store_state = FRX_ADD_ADDRESS; + } + /* + * end of frame detected + * no error occured, frame complete + * if we are in INFORMATION state we have to keep in mind the FCS at MRU check + */ + else if(((ppp_data->frx.stored_len + d_offset) >= 4) && + (((ppp_data->frx.stored_len + d_offset) <= ppp_data->mru) || + (((ppp_data->frx.stored_len + d_offset) <= + (ppp_data->mru + 2)) && + (store_state EQ FRX_ADD_INFORMATION))) && + (fcs EQ PPP_GOODFCS)) + { + /* + * determine the length of the packet + */ + packet_len = 0; + ppp_data->frx.stored_len += d_offset; + ppp_data->frx.cur_desc->len = d_offset; + switch(store_state) + { + case FRX_ADD_INFORMATION: + packet_len = ppp_data->frx.stored_len - 2; + break; + + case FRX_ADD_FCS1: + packet_len = ppp_data->frx.stored_len - 1; + break; + + case FRX_ADD_FCS2: + packet_len = ppp_data->frx.stored_len; + break; + } /*lint !e744 switch statement has no default */ + if(packet_len < ppp_data->frx.stored_len) + { + /* + * remove FCS + */ + ppp_data->frx.stored_len = packet_len; + temp_desc = ppp_data->frx.stored_packet; + while(packet_len > temp_desc->len) + { + packet_len-= temp_desc->len; + temp_desc = (T_desc2*)temp_desc->next; + } + temp_desc->len = packet_len; + /* + * free the rest of packet + */ + arb_discard_packet((T_desc2*)temp_desc->next); + temp_desc->next = (ULONG)NULL; + } +#ifdef PPP_HDLC_TRACE + /* + * remove stored HDLC frame because of correct reception + * the storage of the next PPP frame is done + * in the next call of frx_add_desc() + */ + MFREE_DESC2(ppp_data->frx.hdlc_frame); + ppp_data->frx.hdlc_frame = NULL; +#endif /* PPP_HDLC_TRACE */ + /* + * esape loop + */ + ppp_data->frx.frame_complete = TRUE; + store_state = FRX_ADD_HDLC_BEGIN; + break; + } + /* + * end of frame detected + * error occured, discard frame + */ + else + { + /* + * error traces + */ + if(((ppp_data->frx.stored_len + d_offset) >= 4) && + (fcs NEQ PPP_GOODFCS)) + { + TRACE_EVENT("ERROR HDLC PACKET PPP FCS FAULT"); + } + else if((ppp_data->frx.stored_len + d_offset) > ppp_data->mru) + { + TRACE_EVENT_P3("ERROR PPP PACKET TO LONG stored_len=%d d_offset=%d mru=%d", + ppp_data->frx.stored_len, + d_offset, + ppp_data->mru); + } +#ifdef PPP_HDLC_TRACE + if((ppp_data->frx.stored_len + d_offset) > 0) + { + /* + * trace HDLC frame and store next frame + */ + TRACE_EVENT("wrong HDLC frame:"); + i = 0; + trace_pos = 0; + trace_desc2 = ppp_data->frx.hdlc_frame; + while(trace_desc2) + { + i+= sprintf(&buf[i], + "0x%02x, ", + trace_desc2->buffer[trace_pos]); + trace_pos++; + if(trace_desc2->len <= trace_pos) + { + trace_desc2 = (T_desc2*)trace_desc2->next; + trace_pos = 0; + } + if(i > 80) + { + TRACE_EVENT( buf ); + i = 0; + } + } + if(i > 0) + { + TRACE_EVENT( buf ); + i = 0; + } + } + /* + * release stored HDLC frame + */ + MFREE_DESC2(ppp_data->frx.hdlc_frame); + ppp_data->frx.hdlc_frame = NULL; + /* + * store next HDLC frame + */ + /* + * set source pointer + */ + trace_desc = source_desc; + trace_pos = s_offset; + /* + * allocate first descriptor to store new HDLC frame + */ + MALLOC(trace_desc2, (USHORT)(sizeof(T_desc2) - 1 + + FRX_ADD_SMALL_PACKET_SIZE)); + trace_desc2->len = 0; + trace_desc2->next = (ULONG)NULL; + ppp_data->frx.hdlc_frame = trace_desc2; + + /* + * store first HDLC flag + */ + TRACE_EVENT_P2("start flag found in desc=0x%08x pos=%d", + trace_desc, + trace_pos); + trace_desc2->buffer[trace_desc2->len] = + trace_desc->buffer[trace_pos]; + trace_desc2->len++; + trace_pos++; + while((trace_desc) && (trace_pos >= trace_desc->len)) + { + trace_desc = (T_desc2*)trace_desc->next; + trace_pos = 0; + } + if(trace_desc) + { + /* + * store HDLC frame + */ + while((trace_desc) && + (trace_desc->buffer[trace_pos] NEQ PPP_HDLC_FLAG)) + { + if(trace_desc2->len >= FRX_ADD_SMALL_PACKET_SIZE) + { + MALLOC(trace_desc3, (USHORT)(sizeof(T_desc2) - 1 + + FRX_ADD_SMALL_PACKET_SIZE)); + trace_desc3->len = 0; + trace_desc3->next = (ULONG)NULL; + trace_desc2->next = (ULONG)trace_desc3; + trace_desc2 = trace_desc3; + } + trace_desc2->buffer[trace_desc2->len] = + trace_desc->buffer[trace_pos]; + trace_desc2->len++; + trace_pos++; + while((trace_desc) && (trace_pos >= trace_desc->len)) + { + trace_desc = (T_desc2*)trace_desc->next; + trace_pos = 0; + } + } + /* + * store last HDLC flag + */ + if(trace_desc) + { + if(trace_desc2->len >= FRX_ADD_SMALL_PACKET_SIZE) + { + MALLOC(trace_desc3, (USHORT)(sizeof(T_desc2) - 1 + + FRX_ADD_SMALL_PACKET_SIZE)); + trace_desc3->len = 0; + trace_desc3->next = (ULONG)NULL; + trace_desc2->next = (ULONG)trace_desc3; + trace_desc2 = trace_desc3; + } + TRACE_EVENT_P2("stop flag found in desc=0x%08x pos=%d", + trace_desc, + trace_pos); + trace_desc2->buffer[trace_desc2->len] = + trace_desc->buffer[trace_pos]; + trace_desc2->len++; + trace_pos++; + } + } +#endif /* PPP_HDLC_TRACE */ + /* + * remove receiced packet because of an error + * decrease source offset beacause the HDLC end flag + * can also be the HDLC start flag of the next frame + */ + s_offset--; + arb_discard_packet(ppp_data->frx.stored_packet); + ppp_data->frx.stored_packet = NULL; + store_state = FRX_ADD_HDLC_BEGIN; + } + } + /* + * detect Control Escape octet + */ + else if((currentbyte EQ PPP_HDLC_ESCAPE) && (escape EQ FALSE)) + { + escape = TRUE; + } + /* + * usual octet + */ + else + { + /* + * bit 5 complement for the octet followed by Control Escape + */ + if(escape EQ TRUE) + { + currentbyte^= 0x20; + escape = FALSE; + } + /* + * calculate FCS + */ +#ifdef _SIMULATION_ + fcs = (fcs << 8) + currentbyte; /*lint !e734 Loss of precision */ +#else /* _SIMULATION_ */ + fcs = (fcs >> 8) ^ fcstab[(fcs ^ currentbyte) & 0xff]; +#endif /* _SIMULATION_ */ + /* + * store the packet and determine the protocol + */ + switch(store_state) + { + case FRX_ADD_INFORMATION: + if(d_offset >= d_size) + { + if((ppp_data->frx.stored_len + d_offset) < ppp_data->mru) + { + /* + * allocate new descriptor + */ + switch(ppp_data->frx.stored_ptype) + { + case DTI_PID_LCP: + case DTI_PID_PAP: + case DTI_PID_CHAP: + case DTI_PID_IPCP: + /* + * allocate a big descriptor, copy the data into the new + * one and free the small descriptor + */ + MALLOC (ppp_data->frx.stored_packet, + (USHORT)(sizeof(T_desc2) - 1 + ppp_data->mru)); + memcpy(ppp_data->frx.stored_packet->buffer, + destination, + d_offset); /*lint !e668 Possibly passing a null pointer */ + MFREE(ppp_data->frx.cur_desc); + ppp_data->frx.cur_desc = ppp_data->frx.stored_packet; + ppp_data->frx.cur_desc->next = (ULONG)NULL; + destination = ppp_data->frx.cur_desc->buffer; + d_size = ppp_data->mru; + break; + + default: + /* + * allocate a new small descriptor + */ + MALLOC (temp_desc, (USHORT)(sizeof(T_desc2) - 1 + + FRX_ADD_SMALL_PACKET_SIZE)); + ppp_data->frx.cur_desc->next = (ULONG)temp_desc; + ppp_data->frx.cur_desc->len = d_offset; + ppp_data->frx.cur_desc = temp_desc; + ppp_data->frx.cur_desc->next = (ULONG)NULL; + ppp_data->frx.stored_len += d_offset; + destination = ppp_data->frx.cur_desc->buffer; + d_offset = 0; + d_size = FRX_ADD_SMALL_PACKET_SIZE; + break; + } + } + else if((ppp_data->frx.stored_len + d_offset) >= + (ppp_data->mru + 2)) + { + /* + * remove receiced packet because it is to long + */ + arb_discard_packet(ppp_data->frx.stored_packet); + ppp_data->frx.stored_packet = NULL; + store_state = FRX_ADD_ERROR; + + TRACE_EVENT("ERROR PPP: HDLC packet to long"); +#ifdef PPP_HDLC_TRACE + /* + * trace HDLC frame + */ + TRACE_EVENT("wrong HDLC frame:"); + i = 0; + trace_pos = 0; + trace_desc2 = ppp_data->frx.hdlc_frame; + while(trace_desc2) + { + i+= sprintf(&buf[i], + "0x%02x, ", + trace_desc2->buffer[trace_pos]); + trace_pos++; + if(trace_desc2->len <= trace_pos) + { + trace_desc2 = (T_desc2*)trace_desc2->next; + trace_pos = 0; + } + if(i > 80) + { + TRACE_EVENT( buf ); + i = 0; + } + } + if(i > 0) + { + TRACE_EVENT( buf ); + i = 0; + } + /* + * release stored HDLC frame + */ + MFREE_DESC2(ppp_data->frx.hdlc_frame); + ppp_data->frx.hdlc_frame = NULL; +#endif /* PPP_HDLC_TRACE */ + break; + } + else if((ppp_data->frx.stored_len + d_offset) >= + (ppp_data->mru + 1)) + { + d_offset--; + store_state = FRX_ADD_FCS2; + break; + } + else + { + store_state = FRX_ADD_FCS1; + break; + } + } + /* + * copy data + */ + destination[d_offset] = currentbyte; /*lint !e613 Possible use of null pointer */ + /* + * increase destination offset + */ + d_offset++; + break; + + case FRX_ADD_CONTROL: + if(currentbyte EQ 0x03) + store_state = FRX_ADD_PROTOCOL1; + else + { + TRACE_EVENT("ERROR PPP: wrong HDLC control field"); +#ifdef PPP_HDLC_TRACE + /* + * trace HDLC frame + */ + TRACE_EVENT("wrong HDLC frame:"); + i = 0; + trace_pos = 0; + trace_desc2 = ppp_data->frx.hdlc_frame; + while(trace_desc2) + { + i+= sprintf(&buf[i], "0x%02x, ", trace_desc2->buffer[trace_pos]); + trace_pos++; + if(trace_desc2->len <= trace_pos) + { + trace_desc2 = (T_desc2*)trace_desc2->next; + trace_pos = 0; + } + if(i > 80) + { + TRACE_EVENT( buf ); + i = 0; + } + } + if(i > 0) + { + TRACE_EVENT( buf ); + i = 0; + } + /* + * release stored HDLC frame + */ + MFREE_DESC2(ppp_data->frx.hdlc_frame); + ppp_data->frx.hdlc_frame = NULL; +#endif /* PPP_HDLC_TRACE */ + store_state = FRX_ADD_ERROR; + } + break; + + case FRX_ADD_ADDRESS: + if(currentbyte EQ 0xff) + { + store_state = FRX_ADD_CONTROL; + break; + } + /* + * address and control field compression detected + */ + /* fall through */ + case FRX_ADD_PROTOCOL1: + if((currentbyte & 0x01) EQ 0) + { + ppp_data->frx.stored_ptype = currentbyte; + ppp_data->frx.stored_ptype = (ppp_data->frx.stored_ptype << 8); /*lint !e734 Loss of precision */ + store_state = FRX_ADD_PROTOCOL2; + break; + } + /* + * protocol field compression detected + */ + /* fall through */ + case FRX_ADD_PROTOCOL2: + if(currentbyte & 0x01) + { + /* + * store protocol + */ + ppp_data->frx.stored_ptype|= currentbyte; + /* + * allocate new packet + */ + d_size = FRX_ADD_SMALL_PACKET_SIZE; + /* + * Allocate the necessary size for the data descriptor. + * The size is calculated as follows: + * - take the size of a descriptor structure + * - subtract one because of the array buffer[1] to get + * the size of descriptor control information + * - add number of octets of descriptor data + */ + MALLOC (ppp_data->frx.stored_packet, + (USHORT)(sizeof(T_desc2) - 1 + d_size)); + ppp_data->frx.cur_desc = ppp_data->frx.stored_packet; + ppp_data->frx.cur_desc->next = (ULONG)NULL; + destination = ppp_data->frx.cur_desc->buffer; + d_offset = 0; + store_state = FRX_ADD_INFORMATION; + } + else + { + TRACE_EVENT("ERROR PPP: wrong HDLC protocol field"); +#ifdef PPP_HDLC_TRACE + /* + * trace HDLC frame + */ + TRACE_EVENT("wrong HDLC frame:"); + i = 0; + trace_pos = 0; + trace_desc2 = ppp_data->frx.hdlc_frame; + while(trace_desc2) + { + i+= sprintf(&buf[i], "0x%02x, ", trace_desc2->buffer[trace_pos]); + trace_pos++; + if(trace_desc2->len <= trace_pos) + { + trace_desc2 = (T_desc2*)trace_desc2->next; + trace_pos = 0; + } + if(i > 80) + { + TRACE_EVENT( buf ); + i = 0; + } + } + if(i > 0) + { + TRACE_EVENT( buf ); + i = 0; + } + /* + * release stored HDLC frame + */ + MFREE_DESC2(ppp_data->frx.hdlc_frame); + ppp_data->frx.hdlc_frame = NULL; +#endif /* PPP_HDLC_TRACE */ + store_state = FRX_ADD_ERROR; + } + break; + + case FRX_ADD_FCS1: + store_state = FRX_ADD_FCS2; + break; + + case FRX_ADD_FCS2: + /* + * remove receiced packet because its to long + */ + arb_discard_packet(ppp_data->frx.stored_packet); + ppp_data->frx.stored_packet = NULL; + store_state = FRX_ADD_ERROR; + + TRACE_EVENT("ERROR PPP: HDLC packet to long"); +#ifdef PPP_HDLC_TRACE + /* + * trace HDLC frame + */ + TRACE_EVENT("wrong HDLC frame:"); + i = 0; + trace_pos = 0; + trace_desc2 = ppp_data->frx.hdlc_frame; + while(trace_desc2) + { + i+= sprintf(&buf[i], "0x%02x, ", trace_desc2->buffer[trace_pos]); + trace_pos++; + if(trace_desc2->len <= trace_pos) + { + trace_desc2 = (T_desc2*)trace_desc2->next; + trace_pos = 0; + } + if(i > 80) + { + TRACE_EVENT( buf ); + i = 0; + } + } + if(i > 0) + { + TRACE_EVENT( buf ); + i = 0; + } + /* + * release stored HDLC frame + */ + MFREE_DESC2(ppp_data->frx.hdlc_frame); + ppp_data->frx.hdlc_frame = NULL; +#endif /* PPP_HDLC_TRACE */ + break; + + case FRX_ADD_ERROR: + /* + * we wait for the next HDLC flag + */ + break; + + case FRX_ADD_HDLC_BEGIN: + TRACE_ERROR("ERROR: frx_add_desc(): in FRX_ADD_HDLC_BEGIN state without HDLC flag"); + break; + + default: + TRACE_ERROR("ERROR: frx_add_desc(): wrong state"); + break; + } + } + } + /* + * check if current descriptor is complete analyzed + */ + if(s_offset >= s_size) + { + temp_desc = (T_desc2*)source_desc->next; + MFREE(source_desc); + source_desc = temp_desc; + s_offset = 0; + } + } + /* + * store important values in global variables + */ + switch(store_state) + { + case FRX_ADD_INFORMATION: + case FRX_ADD_FCS1: + case FRX_ADD_FCS2: + ppp_data->frx.cur_desc->len = d_offset; + break; + } /*lint !e744 switch statement has no default */ + ppp_data->frx.store_state = store_state; + ppp_data->frx.calc_fcs = fcs; + ppp_data->frx.escape = escape; + ppp_data->frx.received_data = source_desc; + ppp_data->frx.cur_desc_size = d_size; + ppp_data->frx.proceed_data = s_offset; +} /*lint !e550 fcstab not accessed in _SIMULATION_ frx_add_desc() */ +#endif /* PPP_FLASH_ROM */ + + + +#ifndef PPP_INT_RAM +/* ++------------------------------------------------------------------------------ +| Function : frx_detect_frame ++------------------------------------------------------------------------------ +| Description : The function frx_detect_frame() detects begin and end of +| PPP frames. +| +| Parameters : no parameters +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void frx_detect_frame () +{ + UBYTE* source; + UBYTE* destination; + T_desc2* temp_desc1; + T_desc2* temp_desc2; + + TRACE_FUNCTION( "frx_detect_frame" ); + + /* + * copy received data stream pointer + */ + temp_desc1 = ppp_data->frx.received_data; + /* + * set destination pointer if necessary + */ + if(ppp_data->frx.store_state EQ FRX_ADD_INFORMATION) + { + /* + * to avoid erroneuos code generation of target compiler, + * it is written in two lines instead of one + */ + destination = ppp_data->frx.cur_desc->buffer; + destination+= ppp_data->frx.cur_desc->len; + } + + /* + * while there is still data to analyze and + * a complete frame is not yet received + */ + while((temp_desc1) && (ppp_data->frx.frame_complete EQ FALSE)) + { + /* + * set source pointer + */ + source = &temp_desc1->buffer[ppp_data->frx.proceed_data]; + /* + * We count down the length of the current descriptor. + * while the current descriptor is not yet complete analyzed and + * a complete frame is not yet received + */ + while((temp_desc1->len) && (ppp_data->frx.frame_complete EQ FALSE)) + { + switch(ppp_data->frx.store_state) + { + case FRX_ADD_ERROR: + /* + * search for next HDLC flag + */ + while((temp_desc1->len) && + (*source NEQ PPP_HDLC_FLAG)) + { + /* + * increase source pointer + */ + source++; + temp_desc1->len--; + ppp_data->frx.proceed_data++; + } + if(temp_desc1->len EQ 0) /*lint !e661 Possible access of out-of-bounds pointer */ + /* + * end of descriptor reached + * analyze next descriptor + */ + break; + ppp_data->frx.store_state = FRX_ADD_HDLC_BEGIN; + /* fall through */ + case FRX_ADD_HDLC_BEGIN: + /* + * create new packet (frame) to store detected frame + */ + ppp_data->frx.stored_len = 0; + ppp_data->frx.stored_ptype = DTI_PID_UOS; + ppp_data->frx.cur_desc_size = FRX_ADD_SMALL_PACKET_SIZE; + /* + * Allocate the necessary size for the data descriptor. The size is + * calculated as follows: + * - take the size of a descriptor structure + * - subtract one because of the array buffer[1] to get the size of + * descriptor control information + * - add number of octets of descriptor data + */ + MALLOC (ppp_data->frx.stored_packet, + (USHORT)(sizeof(T_desc2) - 1 + FRX_ADD_SMALL_PACKET_SIZE)); + ppp_data->frx.cur_desc = ppp_data->frx.stored_packet; + ppp_data->frx.cur_desc->len = 0; + ppp_data->frx.cur_desc->next = (ULONG)NULL; + destination = ppp_data->frx.cur_desc->buffer; + + *destination = *source; /*lint !e613 Possible use of null pointer */ + /* + * increase source pointer + */ + source++; /*lint !e613 Possible use of null pointer */ + temp_desc1->len--; + ppp_data->frx.proceed_data++; + /* + * increase destination pointer + */ + ppp_data->frx.stored_len++; + destination++; + ppp_data->frx.cur_desc->len++; + + ppp_data->frx.store_state = FRX_ADD_INFORMATION; + break; + + case FRX_ADD_INFORMATION: + /* + * copy data + */ + while((temp_desc1->len) && + (ppp_data->frx.stored_len < ppp_data->mru) && + (ppp_data->frx.cur_desc->len < ppp_data->frx.cur_desc_size) && + (*source NEQ PPP_HDLC_FLAG)) + { + /* + * copy data + */ + *destination = *source; /*lint !e644 destination may not have been initialized */ + /* + * increase source pointer + */ + source++; + temp_desc1->len--; + ppp_data->frx.proceed_data++; + /* + * increase destination pointer + */ + ppp_data->frx.stored_len++; + destination++; + ppp_data->frx.cur_desc->len++; + } + /* + * analyze why the loop is left + */ + if(ppp_data->frx.stored_len < ppp_data->mru) /*lint !e661 Possible access of out-of-bounds pointer */ + { + if(ppp_data->frx.cur_desc->len >= ppp_data->frx.cur_desc_size) + { + /* + * allocate a new small descriptor + */ + MALLOC (temp_desc2, (USHORT)(sizeof(T_desc2) - 1 + + FRX_ADD_SMALL_PACKET_SIZE)); + ppp_data->frx.cur_desc->next = (ULONG)temp_desc2; + ppp_data->frx.cur_desc = + (T_desc2*)ppp_data->frx.cur_desc->next; + ppp_data->frx.cur_desc->len = 0; + ppp_data->frx.cur_desc->size = 0; + ppp_data->frx.cur_desc->offset = 0; + ppp_data->frx.cur_desc->next = (ULONG)NULL; + ppp_data->frx.cur_desc_size = FRX_ADD_SMALL_PACKET_SIZE; + destination = ppp_data->frx.cur_desc->buffer; + } + if((temp_desc1->len) && + (*source EQ PPP_HDLC_FLAG)) /*lint !e613 Possible use of null pointer */ + { + /* + * end of frame detected + */ + ppp_data->frx.store_state = FRX_ADD_HDLC_BEGIN; + /* + * copy HDLC flag + */ + *destination = *source; /*lint !e613 Possible use of null pointer */ + /* + * increase length values + */ + ppp_data->frx.stored_len++; + ppp_data->frx.cur_desc->len++; + /* + * check for correct length + */ + if(ppp_data->frx.stored_len > 2) + { + /* + * no error occured, frame complete + */ + ppp_data->frx.frame_complete = TRUE; + } + else + { + /* + * remove receiced packet because its to short + */ + arb_discard_packet(ppp_data->frx.stored_packet); + ppp_data->frx.stored_packet = NULL; + } + } + } + else + { + /* + * remove receiced packet because its to long + */ + arb_discard_packet(ppp_data->frx.stored_packet); + ppp_data->frx.stored_packet = NULL; + ppp_data->frx.store_state = FRX_ADD_ERROR; + } + break; + } /*lint !e744 switch statement has no default */ + } + if(temp_desc1->len EQ 0) + { + temp_desc2 = (T_desc2*)temp_desc1->next; + MFREE(temp_desc1); + temp_desc1 = temp_desc2; + ppp_data->frx.proceed_data = 0; + } + } + /* + * store received data stream pointer + */ + ppp_data->frx.received_data = temp_desc1; +} /* frx_detect_frame() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : frx_send_pack_ready_mode() ++------------------------------------------------------------------------------ +| Description : send as many packets to ptx as can be extracted from received frame. +| Frx is in ready mode. +| +| Parameters : no parameters +| ++------------------------------------------------------------------------------ +*/ + +GLOBAL void frx_send_pack_ready_mode () +{ + T_desc2* temp_desc; + + TRACE_FUNCTION( "frx_send_pack_ready_mode ()" ); + + while( ppp_data->frx.frame_complete EQ TRUE AND + ppp_data->frx.data_flow_state EQ FRX_DATA_FLOW_READY) + { + /* + * to avoid any side effects + * first reset all necessary variables and then call the signal + */ + ppp_data->frx.frame_complete = FALSE; + temp_desc = ppp_data->frx.stored_packet; + ppp_data->frx.stored_packet = NULL; + sig_frx_ptx_packet_ind(ppp_data->frx.stored_ptype, + ppp_data->frx.stored_len, + temp_desc); + frx_add_desc(); + } +} + + +/* ++------------------------------------------------------------------------------ +| Function : frx_send_pack_transp_mode ++------------------------------------------------------------------------------ +| Description : send as many packets to ptx as can be extracted from received frame. +| Frx is in transparent mode . +| +| Parameters : no parameters +| ++------------------------------------------------------------------------------ +*/ + +GLOBAL void frx_send_pack_transp_mode () +{ + T_desc2* temp_desc; + + TRACE_FUNCTION( "frx_send_pack_transp_mode ()" ); + + while( ppp_data->frx.frame_complete EQ TRUE AND + ppp_data->frx.data_flow_state EQ FRX_DATA_FLOW_READY) + { + /* + * to avoid any side effects + * first reset all necessary variables and then call the signal + */ + ppp_data->frx.frame_complete = FALSE; + temp_desc = ppp_data->frx.stored_packet; + ppp_data->frx.stored_packet = NULL; + sig_frx_ptx_packet_ind(ppp_data->frx.stored_ptype, + ppp_data->frx.stored_len, + temp_desc); + frx_detect_frame(); + } + +} + +#endif /* PPP_INT_RAM */ +