FreeCalypso > hg > fc-tourmaline
view src/g23m-fad/ppp/ppp_frxf.c @ 78:c632896652ba
mfw/ti1_key.c: properly initialize notified_keys array
The code in this ti1_key.c layer needs to call kpd_subscribe() and
kpd_define_key_notification() functions in order to register with the
KPD driver. The original code passed KPD_NB_PHYSICAL_KEYS in
nb_notified_keys - this constant is defined to 24 in kpd_cfg.h on all
platforms of interest to us - but it only filled the first 23 slots
in the notified_keys array, resulting in stack garbage being passed
to KPD API functions. The fix consists of initializing the last
missed array slot to KPD_KEY_RECORD, the key ID for the right side
button on the D-Sample handset.
On our current hw targets this "Record" button exists as the EXTRA
button on our Luna keypad board and as the camera button on the
Pirelli DP-L10. There is no support whatsoever for this button
in current BMI+MFW, we have no plans of doing anything with Pirelli's
camera button even if we do get our UI fw running on that phone,
and the Mother's dream of building our own FreeCalypso handset with
the same button arrangement as D-Sample (including the right side
button) is currently very nebulous - but let us nonetheless handle
the full set of buttons on the KPD to MFW interface, and let upper
layers weed out unsupported buttons.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 25 Oct 2020 23:41:01 +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 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 */