📄 mprx.c
字号:
/* mpRx.c - MP receive related source file *//* Copyright 1999 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01l,03mar03,ijm in mp_reassemble_ppp_packet, free packet if pfwReceive returns ERROR, SPR# 86148. Removed unnecessary setting of receiving_end.pMblkId->mBlkHdr.mNext to NULL after m_pullup01k,23jan03,ijm removed redundant setting of MT_DATA, SPR#85876, handle case if m_pullup returns NULL, changed logMsg to printf.01j,06aug02,jr fixed build warnings 01i,05may02,ak Changes as part of ARM fixes01h,19feb02,ak input parameter validation in all the functions01g,19sep01,ak removed the check for reassembled packet size > Local MRRU01f,08jul01,ak m_pullup should be used conditionally01e,20jun01,ak pulling up the MBLK chain after reassembly01d,21apr01,nts code clean-up01c,04apr01,nts changed fragments array to fragment list and made associated changes in all the related functions01b,02apr01,nts changed fragments from flat memory to MBLK-CLBLK-clusters01a,20feb01,nts created from routerware source code base*//**$Log:: /Rtrware/devdrvrs/Mp/mprx.c $ * * 4 2/08/99 12:12p Nishit * Code clean-up * * 3 4/30/98 3:02p Alex * Mp v4.2.0 check in * * 1 4/24/98 12:56a Release Engineer * code cleanup, code style changes, * linted, system level test * MP v4.2.0*//*DESCRIPTIONThis module implements the MP receive related functions. It receives theMP fragments from the MP Interface layer and passes it onto the MPre-assembly module which takes care of buffering the fragments and thenre-assembling them into a PPP packet, finally sending the PPP packet UPin the stack.INCLUDES : mpFramingLayerP.h pfwInterfaceP.h vpppstr.h vlcpstr.h*//* includes */#include "vxWorks.h"#include "stdio.h"#include "stdlib.h"#include "private/ppp/mpFramingLayerP.h"#include "netBufLib.h"#include "private/pfw/pfwInterfaceP.h"#include "private/ppp/vpppstr.h"#include "private/ppp/vlcpstr.h"#include "logLib.h"/* imports */IMPORT TEST mp_search_packet_with_all_fragments_received (PFW_PLUGIN_OBJ_STATE *, ULONG *, ULONG *, ULONG);IMPORT TEST mp_search_packet_with_all_fragments_received (PFW_PLUGIN_OBJ_STATE *, ULONG *, ULONG *, ULONG);IMPORT void mp_check_and_handle_frame_lost (PFW_PLUGIN_OBJ_STATE *, ULONG);IMPORT TEST mp_buffer_ppp_fragment (PFW_PLUGIN_OBJ_STATE *, M_BLK_ID, USHORT, enum FRAGMENT_FLAG, ULONG, ULONG *);IMPORT M_BLK_ID mp_reassemble_fragments_to_ppp_packet (PFW_PLUGIN_OBJ_STATE *, ULONG, ULONG, USHORT *);IMPORT ULONG mp_get_M (PFW_PLUGIN_OBJ_STATE *);/* LOCALs & forwards */TEST mp_reassemble_ppp_packet (PFW_PLUGIN_OBJ_STATE *, ULONG);void reassemble_and_dispatch_mp_packet (PFW_PLUGIN_OBJ_STATE *, PFW_STACK_OBJ *, M_BLK_ID );LOCAL ULONG get_mp_sequence_number (PFW_PLUGIN_OBJ_STATE *, UNION_MP_PACKET *);LOCAL TEST verify_reassembled_ppp_packet (PFW_PLUGIN_OBJ_STATE *, PPP_PACKET *, USHORT);LOCAL void convert_long_sequence_number_mp_packet_to_host_order (UNION_MP_PACKET *);LOCAL void convert_short_sequence_number_mp_packet_to_host_order (UNION_MP_PACKET *);LOCAL void check_for_frame_lost (PFW_PLUGIN_OBJ_STATE *, USHORT);LOCAL void get_packet_information (PFW_PLUGIN_OBJ_STATE *, PPP_PACKET *, USHORT, UNION_MP_PACKET **, USHORT *, ULONG *, enum FRAGMENT_FLAG *);LOCAL void update_buffer_information (PFW_PLUGIN_OBJ_STATE *, enum FRAGMENT_FLAG);LOCAL enum FRAGMENT_FLAG get_mp_fragment_flag (PFW_PLUGIN_OBJ_STATE *, UNION_MP_PACKET *);LOCAL UNION_MP_PACKET *get_handle_of_mp_packet (PFW_PLUGIN_OBJ_STATE *, PPP_PACKET *, USHORT, USHORT *);#ifdef PPP_DEBUGLOCAL char *mp_fragment_flag_enum_to_string (enum FRAGMENT_FLAG);#endif /* PPP_DEBUG *//********************************************************************************* reassemble_and_dispatch_mp_packet - Re-assembles and dispatches the MP packet.* * This function is called by the mpFramingLayerReceive function, whenever a * packet is received. This function, gets the information of sequence number,* fragment flag etc. from the packet, and buffers the ppp fragment. * It re-assembles the ppp packet and sends it UP in the stack. If the * re-assembly of the packet fails, it checks for the probable loss of * (B) or (E) or Non-End fragments** RETURNS: N/A*/void reassemble_and_dispatch_mp_packet ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, PFW_STACK_OBJ *pMemberStack, M_BLK_ID packet ) { unsigned int linkIndex = 0; unsigned int current_link = 0; PPP_PACKET *ptr_ppp_packet = NULL; UNION_MP_PACKET *uptr_mp_packet = NULL; USHORT mp_packet_length = 0; ULONG ppp_packet_length = 0; ULONG sequence_number = 0; enum FRAGMENT_FLAG fragment_flag; ULONG current_fragment_index = 0; BOOL isInBundle = FALSE; MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; if ((pMpFramingLayerState == NULL) || (pMemberStack == NULL) || (packet == NULL)) return; /* check if the link is in the receiving end of the bundle */ for (linkIndex = 0; linkIndex < MAX_NO_OF_PPP_PORTS; linkIndex++) { if (pStackData->bundle.receiving_end.links[linkIndex].pMemberStackObj == pMemberStack) { isInBundle = TRUE; current_link = linkIndex; break; } } if (isInBundle == FALSE) return; /* get ppp packet from the M_BLK */ ptr_ppp_packet = mtod (packet, PPP_PACKET *); if (packet->mBlkHdr.mNext != NULL) ppp_packet_length = (ULONG) packet->mBlkPktHdr.len; else ppp_packet_length = (ULONG) packet->mBlkHdr.mLen; /* get the packet information */ get_packet_information (pMpFramingLayerState, ptr_ppp_packet, ppp_packet_length, &uptr_mp_packet, &mp_packet_length, &sequence_number, &fragment_flag); /* increment the mData pointer, adjust the length */ packet->mBlkHdr.mData += sizeof (PPP_HEADER); if (packet->mBlkHdr.mNext != NULL) { packet->mBlkPktHdr.len -= sizeof (PPP_HEADER); packet->mBlkHdr.mLen -= sizeof (PPP_HEADER); } else packet->mBlkHdr.mLen -= sizeof (PPP_HEADER);#ifdef PPP_DEBUG printf ("MP Rx: Fragment (seq# = 0x%x, flag = %s) link 0x%x bundle 0x%x\n", (int) sequence_number, mp_fragment_flag_enum_to_string (fragment_flag), (int) current_link, (int) pMpFramingLayerState->stackObj);#endif /* PPP_DEBUG */ /* update the sequence number */ pStackData->bundle.receiving_end.links [current_link]. most_recently_received_sequence_number = sequence_number; /* check if the receiver is resynchronizing */ if ((pStackData->bundle.receiving_end.buffer.receiver_is_resynchronizing == TRUE) && (fragment_flag != FIRST_FRAGMENT) && (fragment_flag != ONLY_FRAGMENT)) {#ifdef PPP_DEBUG printf ("MP Rx: discarding fragment (seq 0x%x flag = %s) link 0x%x bundle 0x%x\n", (int) sequence_number, mp_fragment_flag_enum_to_string (fragment_flag), (int) current_link, (int) pMpFramingLayerState->stackObj);#endif /* PPP_DEBUG */ return; } /* update the buffer information */ update_buffer_information (pMpFramingLayerState, fragment_flag); /* buffer the ppp fragment into the fragment buffer */ if (mp_buffer_ppp_fragment (pMpFramingLayerState, packet, mp_packet_length, fragment_flag, sequence_number, ¤t_fragment_index) == FAIL) { return; }#ifdef PPP_DEBUG printf ("MP Rx: buffered frag (seq 0x%x flag = %s) length 0x%x link 0x%x bundle 0x%x\n", (int) sequence_number, mp_fragment_flag_enum_to_string (fragment_flag), (int) mp_packet_length, (int) current_link, (int) pMpFramingLayerState->stackObj);#endif /* PPP_DEBUG */ /* reassemble the ppp packet */ if (mp_reassemble_ppp_packet (pMpFramingLayerState, current_fragment_index) == PASS) { return; } /* check for the loss of frame, if any */ check_for_frame_lost (pMpFramingLayerState, current_link); }/********************************************************************************* mp_reassemble_ppp_packet - Re-assemble the PPP packet.* * This function checks if all the fragments from BEGIN (B) fragment to END (E) * fragment are buffered and then re-assembles the fragments into a PPP packet.* Verifies if the packet is re-assembled and if the re-assembled packet is of * correct type and then adds it to the receive queue to send the packet UP in * the stack.** RETURNS: PASS or FAIL*/TEST mp_reassemble_ppp_packet ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, ULONG current_fragment_index ) { ULONG begin_fragment_index = 0; ULONG end_fragment_index = 0; PPP_PACKET *ptr_reassembled_ppp_packet = NULL; USHORT reassembled_ppp_packet_length = 0; UINT pppPacketLength = 0; M_BLK_ID tempMBlk = NULL; MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; if (pMpFramingLayerState == NULL) return FAIL; /* if number of BEGIN and END fragments is greater than zero */ if ((pStackData->bundle.receiving_end.buffer. number_of_beginning_fragments_buffered > 0x0000) && (pStackData->bundle.receiving_end.buffer. number_of_ending_fragments_buffered > 0x0000)) { /* if all the fragments between BEGIN and END is available, based on Seq. No */ if (mp_search_packet_with_all_fragments_received (pMpFramingLayerState, &begin_fragment_index, &end_fragment_index, current_fragment_index) == PASS) { /* then reassemble all the fragments to a single packet */ pStackData->bundle.receiving_end.pMblkId = mp_reassemble_fragments_to_ppp_packet (pMpFramingLayerState, begin_fragment_index, end_fragment_index, &reassembled_ppp_packet_length); if (pStackData->bundle.receiving_end.pMblkId == NULL) {#ifdef PPP_DEBUG printf ("MP: reassembled PPP packet NULL Ptr\n");#endif /* PPP_DEBUG */ return (FAIL); } ptr_reassembled_ppp_packet = mtod (pStackData->bundle.receiving_end.pMblkId, PPP_PACKET *); /* verify the reassembled packet */ if (verify_reassembled_ppp_packet (pMpFramingLayerState, ptr_reassembled_ppp_packet, reassembled_ppp_packet_length) == PASS) { if ((pStackData->bundle.receiving_end.pMblkId->mBlkHdr.mNext != NULL) && (pStackData->bundle.receiving_end.pMblkId->mBlkPktHdr.len < MAX_CLUSTER_SIZE)) { pppPacketLength = pStackData->bundle.receiving_end.pMblkId->mBlkPktHdr.len; tempMBlk = m_pullup(pStackData->bundle.receiving_end.pMblkId, pppPacketLength); if (tempMBlk != NULL) { pStackData->bundle.receiving_end.pMblkId = tempMBlk; pStackData->bundle.receiving_end.pMblkId->mBlkHdr.mLen = pppPacketLength; pStackData->bundle.receiving_end.pMblkId->mBlkHdr.mFlags &= (~M_PKTHDR); } else { /* m_pullup frees original packet if error occurs */ pStackData->bundle.receiving_end.pMblkId = NULL; return (FAIL); } } if (pfwReceive (pMpFramingLayerState, pStackData->bundle.receiving_end.pMblkId) != OK) netMblkClChainFree (pStackData->bundle.receiving_end.pMblkId); } return (PASS); } } return (FAIL); }/********************************************************************************* check_for_frame_lost - check if there is any frame lost during reception.* * This function checks if there is any loss of frame during the reception* and handles the lost frame possibility.** RETURNS: N/A*/LOCAL void check_for_frame_lost ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, USHORT current_link ) { MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; if (pMpFramingLayerState == NULL) return; if (current_link == pStackData->bundle.receiving_end. no_of_links - 0x0001) { /* get the current minimum */ pStackData->bundle.receiving_end.buffer.M = mp_get_M (pMpFramingLayerState); /* check for frame lost */ mp_check_and_handle_frame_lost (pMpFramingLayerState, pStackData->bundle.receiving_end.buffer.M); } }/********************************************************************************* get_packet_information - get the packet information by parsing the packet* structure.* * This function gets the MP packet, sequence number and fragment flag* from the PPP packet** RETURNS: N/A*/LOCAL void get_packet_information
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -