/* iprohc_udp_ip.h - ROHC UDP IP profile head file */ /* * Copyright (c) 2009 Wind River Systems, Inc. * * The right to copy, distribute or otherwise make use of this software * may be licensed only pursuant to the terms of an applicable Wind River * license agreement. No license to Wind River intellectual property rights * is granted herein. All rights not licensed by Wind River are reserved * by Wind River. */ /* modification history -------------------- 01b,12apr10,ggz Resolve 64bit compiler warnings 01a,01dec09,ggz Created */ #ifndef IPROHC_UDP_IP_H #define IPROHC_UDP_IP_H /* **************************************************************************** * INCLUDE FILES **************************************************************************** */ #include #include #include #include "iprohc_config.h" #include "iprohc_constant.h" #include "iprohc_ip.h" #include "iprohc_coding_util.h" #ifdef __cplusplus extern "C" { #endif /* **************************************************************************** * DEFINES **************************************************************************** */ #define IPROHC_ENABLE_REENTRANT /* *=========================================================================== * IPROHC_FMT_UDP_DYNAMIC *=========================================================================== * Fomat dynamic chain in a IR/IR-DYN packet * * * UDP header dynamic part * +---+---+---+---+---+---+---+---+ * / UDP checksum / 2 octets * +---+---+---+---+---+---+---+---+ */ #define IPROHC_FMT_UDP_DYNAMC(udp_context, pointer, has_dynamic, pkt) \ { \ pointer -= 2; \ ipcom_memcpy(&pkt->data[pointer], &udp_context->checksum, 2); \ /* UDP length field is eliminated */ \ has_dynamic = IP_TRUE; \ } /* *=========================================================================== * IPROHC_FMT_UDP_STATIC *=========================================================================== * Fomat dynamic chain in a IR/IR-DYN packet * * UDP header static part * +---+---+---+---+---+---+---+---+ * / UDP source port / 2 octets * +---+---+---+---+---+---+---+---+ * / UDP destination port / 2 octets * +---+---+---+---+---+---+---+---+ */ #define IPROHC_FMT_UDP_STATIC(udp_context, pointer, pkt) \ { \ pointer -= 2; \ ipcom_memcpy(&pkt->data[pointer], &udp_context->dst_port, 2); \ pointer -= 2; \ ipcom_memcpy(&pkt->data[pointer], &udp_context->src_port, 2); \ } /* *=========================================================================== * IPROHC_UDP_UPDATE_CONTEXT *=========================================================================== * Update the UDP context * * Should hdr(UDP Checksum) be nonzero when context(UDP Checksum) is zero, * the header cannot be compressed. It must be sent uncompressed or the context * reinitialized using an IR packet. */ #define IPROHC_UDP_UPDATE_CONTEXT(c_context, udp_context, udp_header, pkt) \ { \ Ip_u16 prev_checksum; \ prev_checksum = udp_context->checksum; \ udp_context->length = udp_header.length; \ udp_context->checksum = udp_header.checksum; \ udp_context->payload = pkt->tlstart + 8; \ \ /* Is there checksum usage switch */ \ if (((prev_checksum == 0) && (udp_context->checksum != 0)) || \ ((prev_checksum != 0) && (udp_context->checksum == 0))) \ { \ /* Update the state of the context to IR */ \ c_context->state = ROHC_COMP_STATE_IR; \ c_context->num_ir = 0; \ c_context->pkt_type = ROHC_PKT_IR; \ } \ \ if(udp_context->checksum != 0) \ udp_context->use_checksum = IP_TRUE; \ else \ udp_context->use_checksum = IP_FALSE; \ } /* *=========================================================================== * IPROHC_UDP_INIT_CONTEXT *=========================================================================== * Set the UDP context */ #define IPROHC_UDP_INIT_CONTEXT(udp_context, udp_header, pkt) \ { \ udp_context->src_port = udp_header.src_port; \ udp_context->dst_port = udp_header.dst_port; \ udp_context->length = udp_header.length; \ udp_context->checksum = udp_header.checksum; \ udp_context->payload = pkt->tlstart + 8; \ \ if(udp_context->checksum != 0) \ udp_context->use_checksum = IP_TRUE; \ else \ udp_context->use_checksum = IP_FALSE; \ } /* *=========================================================================== * IPROHC_GET_UDP_STATIC *=========================================================================== * GET UDP static header part in a IR packet */ #define IPROHC_GET_UDP_STATIC(udp_context, pointer, pkt) \ { \ ipcom_memcpy(&udp_context->src_port, &pkt->data[pointer], 2); \ pointer += 2; \ ipcom_memcpy(&udp_context->dst_port, &pkt->data[pointer], 2); \ pointer += 2; \ } /* *=========================================================================== * IPROHC_GET_UDP_DYNAMIC *=========================================================================== * Get UDP dynamic chain in a IR/IP-DYN packet and set the checksum usage * control */ #define IPROHC_GET_UDP_DYNAMIC(udp_context, pointer, pkt) \ { \ ipcom_memcpy(&udp_context->checksum, &pkt->data[pointer], 2); \ pointer += 2; \ if(udp_context->checksum != 0) \ udp_context->use_checksum = IP_TRUE; \ else \ udp_context->use_checksum = IP_FALSE; \ } /* *=========================================================================== * IPROHC_UPD_UDP_DYNAMIC1 *=========================================================================== * Get UDP dynamic chain in a genral packet * * Checksum controll field can not be updated by general packets. * Only IR packets can update it. Used for general packets. */ #define IPROHC_UPD_UDP_DYNAMIC1(udp_context, pointer, pkt, udp_chksum) \ { \ if (udp_context->use_checksum == IP_TRUE) \ { \ ipcom_memcpy(&udp_context->checksum, &pkt->data[pointer], 2); \ pointer += 2; \ } \ else udp_context->checksum = 0; \ } /* *=========================================================================== * IPROHC_UPD_UDP_STATIC *=========================================================================== * Update UDP static header */ #define IPROHC_UPD_UDP_STATIC(udp_context, pointer, pkt) \ { \ IPROHC_GET_UDP_STATIC(udp_context, pointer, pkt) \ } /* *=========================================================================== * IPROHC_UPD_UDP_DYNAMIC *=========================================================================== * Update UDP dynamic header */ #define IPROHC_UPD_UDP_DYNAMIC(udp_context, pointer, pkt) \ { \ IPROHC_GET_UDP_DYNAMIC(udp_context, pointer, pkt) \ } /* *=========================================================================== * IPROHC_GET_UDP_LENGTH *=========================================================================== * Calculate UDP length. Used with IR, IR-DYN packets. */ #define IPROHC_GET_UDP_LENGTH(udp_context, pkt) \ { \ udp_context->length = (Ip_u16)(pkt->end - udp_context->payload + 8); \ udp_context->length = ipcom_htons(udp_context->length); \ } /* *=========================================================================== * IPROHC_RECONSTRUCT_UDP *=========================================================================== * Reconstruct the packet from UDP context */ #define IPROHC_RECONSTRUCT_UDP(udp_context, pkt) \ { \ Ip_u16 data_tmp = 0; \ pkt->ipstart -= 2; \ if(udp_context->use_checksum == IP_TRUE) \ ipcom_memcpy(&pkt->data[pkt->ipstart], &udp_context->checksum, 2); \ else \ { \ ipcom_memcpy(&pkt->data[pkt->ipstart], &data_tmp, 2); \ } \ pkt->ipstart -= 2; \ ipcom_memcpy(&pkt->data[pkt->ipstart], &udp_context->length, 2); \ pkt->ipstart -= 2; \ ipcom_memcpy(&pkt->data[pkt->ipstart], &udp_context->dst_port, 2); \ pkt->ipstart -= 2; \ ipcom_memcpy(&pkt->data[pkt->ipstart], &udp_context->src_port, 2); \ } /* **************************************************************************** * Public TYPES **************************************************************************** */ /* **************************************************************************** * LOCAL TYPES **************************************************************************** */ typedef struct udp_header_struct { /* Source port */ Ip_u16 src_port; /* Destination port */ Ip_u16 dst_port; /* UDP length */ Ip_u16 length; /* UDP length */ Ip_u16 checksum; }udp_header; /* *=========================================================================== * Iprohc_c_udp_context_struct *=========================================================================== * ROHC compression UDP profile specific context structure */ typedef struct Iprohc_c_udp_context_struct { /* Source port */ Ip_u16 src_port; /* Destination port */ Ip_u16 dst_port; /* UDP length */ Ip_u16 length; /* UDP checksum */ Ip_u16 checksum; /* TRUE if checksum is used */ Ip_bool use_checksum; /* Pointer to UDP payload */ int payload; /* Statistic information */ Ip_u32 udp_pkt_count; } Iprohc_c_udp_context; /* *=========================================================================== * Iprohc_d_udp_context_struct *=========================================================================== * ROHC decompression UDP profile specific context structure */ typedef struct Iprohc_d_udp_context_struct { /* Source port */ Ip_u16 src_port; /* Destination port */ Ip_u16 dst_port; /* UDP length */ Ip_u16 length; /* UDP checksum */ Ip_u16 checksum; /* TRUE if checksum is used */ Ip_bool use_checksum; /* Pointer to UDP payload */ int payload; /* Statistic information */ Ip_u32 udp_pkt_count; } Iprohc_d_udp_context; /* *=========================================================================== * Iprohc_c_udp_ip_context_struct *=========================================================================== * ROHC compression UDP_IP profile specific context structure */ typedef struct Iprohc_c_udp_ip_context_struct { /* IPvX specific context */ Iprohc_c_ip_context *ip_context; /* UDP sepecific context */ Iprohc_c_udp_context *udp_context; } Iprohc_c_udp_ip_context; /* *=========================================================================== * Iprohc_d_udp_ip_context_struct *=========================================================================== * ROHC decompression UDP_IP profile specific context structure */ typedef struct Iprohc_d_udp_ip_context_struct { /* IPvX specific context */ Iprohc_d_ip_context *ip_context; /* UDP sepecific context */ Iprohc_d_udp_context *udp_context; } Iprohc_d_udp_ip_context; /* **************************************************************************** * GLOBAL FUNCTIONS **************************************************************************** */ /* Profile registration/deregistration functions */ IP_PUBLIC Ip_err iprohc_profile_udp_ip_register(void); IP_PUBLIC Ip_err iprohc_udp_ip_deregister(void); /* Profile specific compression functions */ IP_PUBLIC Ip_err iprohc_udp_ip_c_find_context(Iprohc_compressor *comp, Ipcom_pkt *pkt, Iprohc_c_context **c_context); IP_PUBLIC Iprohc_c_context * iprohc_udp_ip_c_create_context(Iprohc_compressor *comp, Ipcom_pkt *pkt); IP_PUBLIC Ip_err iprohc_udp_ip_c_del_context(Iprohc_c_context *context); IP_PUBLIC Ip_err iprohc_udp_ip_c_process_feedback(Iprohc_c_context *context, Ip_u8 *feedback, Ip_u8 size); IP_PUBLIC Ip_err iprohc_udp_ip_c_compress(Iprohc_c_context *context, Ipcom_pkt *pkt); IP_PUBLIC void iprohc_udp_ip_c_print_context(Iprohc_c_context *context); /* Profile specific decompression functions */ IP_PUBLIC Iprohc_d_context * iprohc_udp_ip_d_find_context(Iprohc_decompressor *decomp, Ipcom_pkt *pkt); IP_PUBLIC Iprohc_d_context * iprohc_udp_ip_d_create_context(Iprohc_decompressor *decomp, Ipcom_pkt *pkt); IP_PUBLIC Ip_err iprohc_udp_ip_d_del_context(Iprohc_d_context *context); IP_PUBLIC void iprohc_udp_ip_d_print_context(Iprohc_d_context *context); IP_PUBLIC Ip_err iprohc_udp_ip_d_decompress(Iprohc_d_context *context, Ipcom_pkt *pkt); #ifdef __cplusplus } #endif #endif /* #ifndef IPROHC_UDP_IP_H */ /* **************************************************************************** * END OF FILE **************************************************************************** */