original files of m241
This commit is contained in:
@@ -0,0 +1,554 @@
|
||||
/* iprohc_decomp.h - ROHC decompressor head file */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 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
|
||||
--------------------
|
||||
01i,05Jul12,ggz Defect WIND00351290. Use ipcom_mutex_lock for unix port
|
||||
01h,26aug11,ggz Fix defect WIND00294683. Incorrect ext order in decompressed packet
|
||||
01g,12apr10,ggz Resolve 64bit compiler warnings
|
||||
01f,20apr09,tlu Fix Linux build warnings for mips64 gcc (cav_ebt5800)
|
||||
01e,08jul08,tlu Add to handle IP extension headers
|
||||
01d,10jun08,tlu Fix to convert payload length to network format for IPv6
|
||||
01c,15may08,tlu Fix the macro to check whether decompression is allowed
|
||||
01b,01may08,tlu Add debug function
|
||||
01a,06mar08,tlu Created.
|
||||
*/
|
||||
|
||||
#ifndef IPROHC_DECOMP_H
|
||||
#define IPROHC_DECOMP_H
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_tags.h>
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_list.h>
|
||||
|
||||
|
||||
#include "iprohc_config.h"
|
||||
#include "iprohc_constant.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPROHC_ENABLE_REENTRANT
|
||||
|
||||
|
||||
#ifdef IPROHC_ENABLE_REENTRANT
|
||||
|
||||
#if defined(IP_PORT_VXWORKS) || defined(IP_PORT_UNIX)
|
||||
|
||||
#define IPROHC_DECOMP_LOCK(decomp) ipcom_mutex_lock((decomp)->code_mutex)
|
||||
#define IPROHC_DECOMP_UNLOCK(decomp) ipcom_mutex_unlock((decomp)->code_mutex)
|
||||
|
||||
#define IPROHC_D_CONTEXT_LOCK(context) ipcom_mutex_lock((context)->code_mutex)
|
||||
#define IPROHC_D_CONTEXT_UNLOCK(context) ipcom_mutex_unlock((context)->code_mutex)
|
||||
|
||||
#else /* !IP_PORT_VXWORKS, Linux recursive semaphore */
|
||||
|
||||
#define IPROHC_DECOMP_LOCK(decomp) iprohc_decomp_lck(decomp)
|
||||
#define IPROHC_DECOMP_UNLOCK(decomp) iprohc_decomp_unlck(decomp)
|
||||
|
||||
#define IPROHC_D_CONTEXT_LOCK(context) iprohc_d_context_lck(context)
|
||||
#define IPROHC_D_CONTEXT_UNLOCK(context) iprohc_d_context_unlck(context)
|
||||
|
||||
#endif /* IP_PORT_VXWORKS */
|
||||
|
||||
#else
|
||||
|
||||
#define IPROHC_DECOMP_LOCK(comp) IP_NOOP
|
||||
#define IPROHC_DECOMP_UNLOCK(comp) IP_NOOP
|
||||
|
||||
#define IPROHC_D_CONTEXT_LOCK(context) IP_NOOP
|
||||
#define IPROHC_D_CONTEXT_UNLOCK(context) IP_NOOP
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* IPROHC_DECOMP_ALLOWED
|
||||
*===========================================================================
|
||||
* Check whether decompression is allowed according to RFC 3095, 5.3.2.2.1:
|
||||
* In Full context state, allow to decompress any type of packets;
|
||||
* In Static context state, only IR, IR-DYN, and UOR-2 packets are allowed;
|
||||
* In No context state, only IR packets are allowed.
|
||||
*/
|
||||
#define IPROHC_DECOMP_ALLOWED(context, pkt_type, sn) \
|
||||
{ \
|
||||
Iprohc_feedback *feedback = IP_NULL; \
|
||||
\
|
||||
if (context->state == ROHC_DECOMP_STATE_NO) \
|
||||
{ \
|
||||
if (pkt_type != ROHC_PKT_IR) \
|
||||
{ \
|
||||
/* Send STATIC-NACK feedback */ \
|
||||
feedback = iprohc_create_feedback_2(context, \
|
||||
ROHC_FEEDBACK_STATIC_NACK, sn); \
|
||||
} \
|
||||
} \
|
||||
else if (context->state == ROHC_DECOMP_STATE_STATIC) \
|
||||
{ \
|
||||
if ((pkt_type != ROHC_PKT_IR) && \
|
||||
(pkt_type != ROHC_PKT_IR_DYN) && \
|
||||
(pkt_type != ROHC_PKT_TYPE_2)) \
|
||||
{ \
|
||||
/* Send NACK feedback */ \
|
||||
feedback = iprohc_create_feedback_2(context, \
|
||||
ROHC_FEEDBACK_NACK, sn); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if (feedback != IP_NULL) \
|
||||
{ \
|
||||
if (context->trans == ROHC_DECOMP_TRANS_INITIATED) \
|
||||
/* Feedback pkts that initiate the mode transition must */ \
|
||||
/* carry CRC option */ \
|
||||
iprohc_feedback_add_option(feedback, ROHC_FEEDBACK_OPT_CRC, 1, 0); \
|
||||
\
|
||||
IPROHC_ERROUT(IPCOM_ERR_PERMISSION_DENIED); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* IPROHC_RECONSTRUCT_IP_EXT
|
||||
*===========================================================================
|
||||
* Re-construct an IP extension header from the decompressor context:
|
||||
* - Loop through the reference list to re-construct IP extension headers
|
||||
*/
|
||||
#define IPROHC_RECONSTRUCT_IP_EXT(iprohc_header, pkt) \
|
||||
{ \
|
||||
Iprohc_ref_list *ext_hdr, *n_ext_hdr; \
|
||||
\
|
||||
for (ext_hdr = IPCOM_LIST_LAST(&iprohc_header->ref_head); \
|
||||
ext_hdr; \
|
||||
ext_hdr = n_ext_hdr) \
|
||||
{ \
|
||||
n_ext_hdr = IPCOM_LIST_PREV(&ext_hdr->ref_list); \
|
||||
/* move pointer back for the extension header */ \
|
||||
pkt->ipstart -= ext_hdr->length; \
|
||||
pkt->start = pkt->ipstart; \
|
||||
/* copy the extension header to the packet */ \
|
||||
ipcom_memcpy(&(pkt->data[pkt->ipstart]), ext_hdr->data, \
|
||||
ext_hdr->length); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* IPROHC_RECONSTRUCT_IPV4
|
||||
*===========================================================================
|
||||
* Re-construct an IP header from the decompressor context:
|
||||
* - Calculate datagram length from ipstart/start and end pointers.
|
||||
* - Calculate header checksum.
|
||||
* - Move the ipstart and start pointers
|
||||
* - Copy the IP header to the packet
|
||||
*/
|
||||
#ifdef IPCOM_USE_INET
|
||||
#define IPROHC_RECONSTRUCT_IPV4(iprohc_header, pkt) \
|
||||
{ \
|
||||
if (iprohc_header->has_exten) \
|
||||
{ \
|
||||
/* Re-construct IP extenstion headers */ \
|
||||
IPROHC_RECONSTRUCT_IP_EXT(iprohc_header, pkt); \
|
||||
} \
|
||||
\
|
||||
/* IHL = 5, 20 octets */ \
|
||||
pkt->ipstart -= IPROHC_IP4_HDR_SIZE; \
|
||||
pkt->start = pkt->ipstart; \
|
||||
iprohc_header->header.ip4.length = ip_htons(pkt->end - pkt->start); \
|
||||
\
|
||||
/* Reset checksum to 0 to calculate header checksum */ \
|
||||
iprohc_header->header.ip4.checksum = 0; \
|
||||
iprohc_header->header.ip4.checksum = \
|
||||
ipcom_in_checksum(&iprohc_header->header.ip4, \
|
||||
(Ip_size_t)((iprohc_header->header.ip4.vers_len & 0x0F)*4)); \
|
||||
ipcom_memcpy(&(pkt->data[pkt->ipstart]), &(iprohc_header->header.ip4), \
|
||||
IPROHC_IP4_HDR_SIZE); \
|
||||
}
|
||||
#else
|
||||
#define IPROHC_RECONSTRUCT_IPV4(iprohc_header, pkt) IP_NOOP
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* IPROHC_RECONSTRUCT_IPV6
|
||||
*===========================================================================
|
||||
* Re-construct an IPv6 header from the decompressor context:
|
||||
* - Calculate payload length from ipstart/start and end pointers.
|
||||
* - Move the ipstart and start pointers
|
||||
* - Copy the IPv6 header to the packet
|
||||
*/
|
||||
#ifdef IPCOM_USE_INET6
|
||||
#define IPROHC_RECONSTRUCT_IPV6(iprohc_header, pkt) \
|
||||
{ \
|
||||
if (iprohc_header->has_exten) \
|
||||
{ \
|
||||
/* Re-construct IP extenstion headers */ \
|
||||
IPROHC_RECONSTRUCT_IP_EXT(iprohc_header, pkt); \
|
||||
} \
|
||||
\
|
||||
iprohc_header->header.ip6.plen = ip_htons(pkt->end - pkt->start); \
|
||||
/* IPv6 header length = 40 octets */ \
|
||||
pkt->ipstart -= IPROHC_IP6_HDR_SIZE; \
|
||||
pkt->start = pkt->ipstart; \
|
||||
ipcom_memcpy(&pkt->data[pkt->ipstart], &(iprohc_header->header.ip6), \
|
||||
IPROHC_IP6_HDR_SIZE); \
|
||||
}
|
||||
#else
|
||||
#define IPROHC_RECONSTRUCT_IPV6(iprohc_header, pkt) IP_NOOP
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* IPROHC_RECONSTRUCT_IP
|
||||
*===========================================================================
|
||||
* Re-construct IP headers from the context
|
||||
*/
|
||||
#define IPROHC_RECONSTRUCT_IP(ip_context, pkt) \
|
||||
{ \
|
||||
Iprohc_ip_header *ip_header, *p_ip_header; \
|
||||
\
|
||||
for (ip_header = IPCOM_LIST_LAST(&ip_context->ip_head); \
|
||||
ip_header; \
|
||||
ip_header = p_ip_header) \
|
||||
{ \
|
||||
p_ip_header = IPCOM_LIST_PREV(&ip_header->ip_list); \
|
||||
\
|
||||
if (ip_header->packet_type == ROHC_PKT_IPV4) \
|
||||
{ \
|
||||
/* Re-construct an IPv4 header */ \
|
||||
IPROHC_RECONSTRUCT_IPV4(ip_header, pkt); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* Re-construct an IPv6 header */ \
|
||||
IPROHC_RECONSTRUCT_IPV6(ip_header, pkt); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* IPROHC_D_F_STATE_TRANS
|
||||
*===========================================================================
|
||||
* Process state transition at decompressor when a decompression fails
|
||||
*/
|
||||
#define IPROHC_D_F_STATE_TRANS(d_context, sn) \
|
||||
{ \
|
||||
Ip_u8 ratio; \
|
||||
Iprohc_feedback *feedback_v = IP_NULL; \
|
||||
\
|
||||
/* Calculate the failure ratio */ \
|
||||
ratio = (Ip_u8)((d_context->num_decompressed * 100) % d_context->num_failed); \
|
||||
\
|
||||
/* State transits to Static/No Context: RFC 3095, 5.3.2.1 */ \
|
||||
if (d_context->state == ROHC_DECOMP_STATE_FULL) \
|
||||
{ \
|
||||
if (ratio >= IPROHC_D_FULL_RATIO) \
|
||||
{ \
|
||||
d_context->state = ROHC_DECOMP_STATE_STATIC; \
|
||||
\
|
||||
/* Send NACK */ \
|
||||
feedback_v = iprohc_create_feedback_2(d_context, \
|
||||
ROHC_FEEDBACK_NACK, sn); \
|
||||
} \
|
||||
} \
|
||||
else if (d_context->state == ROHC_DECOMP_STATE_STATIC) \
|
||||
{ \
|
||||
if (ratio >= IPROHC_D_STATIC_RATIO) \
|
||||
{ \
|
||||
d_context->state = ROHC_DECOMP_STATE_NO; \
|
||||
\
|
||||
/* Send NACK */ \
|
||||
feedback_v = iprohc_create_feedback_2(d_context, \
|
||||
ROHC_FEEDBACK_NACK, sn); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if ((feedback_v != IP_NULL) && \
|
||||
(context->trans == ROHC_DECOMP_TRANS_INITIATED)) \
|
||||
{ \
|
||||
/* Feedback pkts that initiate the mode transition must */ \
|
||||
/* carry CRC option */ \
|
||||
iprohc_feedback_add_option(feedback_v, ROHC_FEEDBACK_OPT_CRC, 1, 0); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* IPROHC_D_MODE_TRANS
|
||||
*===========================================================================
|
||||
* Process mode transition at decompressor
|
||||
*/
|
||||
#define IPROHC_D_MODE_TRANS(d_context, mode) \
|
||||
{ \
|
||||
if (mode == ROHC_MODE_C) \
|
||||
{ \
|
||||
/* mode transition request is declined at compressor, */ \
|
||||
/* -- reset trans mode back to mode, and set trans as Pending */ \
|
||||
d_context->trans_mode = d_context->mode; \
|
||||
d_context->trans = ROHC_DECOMP_TRANS_PENDING; \
|
||||
} \
|
||||
else if ((d_context->mode == ROHC_MODE_U) && \
|
||||
(d_context->trans == ROHC_DECOMP_TRANS_DONE)) \
|
||||
{ \
|
||||
/* Initiate the mode transition: U-mode-->O-mode */ \
|
||||
d_context->trans_mode = ROHC_MODE_O; \
|
||||
d_context->trans = ROHC_DECOMP_TRANS_INITIATED; \
|
||||
} \
|
||||
else if (mode == (int)d_context->trans_mode) \
|
||||
{ \
|
||||
/* mode transition request is accepted at compressor, */ \
|
||||
/* -- set trans and mode */ \
|
||||
if (d_context->trans == ROHC_DECOMP_TRANS_INITIATED) \
|
||||
{ \
|
||||
d_context->mode = d_context->trans_mode; \
|
||||
d_context->trans = ROHC_DECOMP_TRANS_PENDING; \
|
||||
} \
|
||||
else if (d_context->trans == ROHC_DECOMP_TRANS_PENDING) \
|
||||
d_context->trans = ROHC_DECOMP_TRANS_DONE; \
|
||||
} \
|
||||
else if ((mode == -1) && (d_context->trans == ROHC_DECOMP_TRANS_PENDING))\
|
||||
{ \
|
||||
d_context->trans = ROHC_DECOMP_TRANS_DONE; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Deompressor states
|
||||
*===========================================================================
|
||||
* refer to RFC 3095, section 4.3.2
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ROHC_DECOMP_STATE_NO = 1,
|
||||
ROHC_DECOMP_STATE_STATIC,
|
||||
ROHC_DECOMP_STATE_FULL
|
||||
} Iprohc_decomp_state;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* De-compressor mode transitions
|
||||
*===========================================================================
|
||||
* refer to RFC 3095, section 5.6.1
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ROHC_DECOMP_TRANS_DONE = 0,
|
||||
ROHC_DECOMP_TRANS_INITIATED,
|
||||
ROHC_DECOMP_TRANS_PENDING
|
||||
} Iprohc_decomp_trans;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* Public TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* LOCAL TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
struct Iprohc_decompressor;
|
||||
struct Iprohc_interface;
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Iprohc_d_context
|
||||
*===========================================================================
|
||||
* This is the ROHC decompression context structure
|
||||
*/
|
||||
|
||||
typedef struct Iprohc_d_context_struct
|
||||
{
|
||||
Ipcom_list context_list;
|
||||
|
||||
/* CID allocated for the context */
|
||||
Ip_u16 cid;
|
||||
|
||||
/* decompression state */
|
||||
Iprohc_decomp_state state;
|
||||
|
||||
/* decompression mode */
|
||||
Iprohc_mode mode;
|
||||
|
||||
/* decompression mode transition */
|
||||
Iprohc_decomp_trans trans;
|
||||
|
||||
/* decompression mode to be transited to */
|
||||
Iprohc_mode trans_mode;
|
||||
|
||||
/* first IR received for context, parsed during creating the context */
|
||||
Ip_bool first_ir;
|
||||
|
||||
/* number of successfully decompressed packets */
|
||||
Ip_u32 num_decompressed;
|
||||
|
||||
/* number of failed decompressed packets */
|
||||
Ip_u32 num_failed;
|
||||
|
||||
/* stream type: IPv4 or IPv6, for feedback processing */
|
||||
Ip_u8 stream_type;
|
||||
|
||||
/* source address of the stream, for feedback processing */
|
||||
Iprohc_addr src;
|
||||
|
||||
/* destination address of the stream, for feedback processing */
|
||||
Iprohc_addr dst;
|
||||
|
||||
/* profile the context is associated with */
|
||||
Ip_u8 profileid;
|
||||
|
||||
/* Compressor the context is associated with */
|
||||
struct Iprohc_decompressor *decompressor;
|
||||
|
||||
/* CRC used to validate the packet */
|
||||
Ip_u8 crc;
|
||||
|
||||
#ifdef IPROHC_ENABLE_REENTRANT
|
||||
Ipcom_mutex code_mutex; /* Mutex to protect compressor data. */
|
||||
#endif
|
||||
|
||||
#ifndef IP_PORT_VXWORKS /* for Linux recursive semaphore */
|
||||
/* the process that currently holds the semaphore and taken counter */
|
||||
Ip_pid_t pid;
|
||||
Ip_u8 s_counter;
|
||||
#endif /* !IP_PORT_VXWORKS */
|
||||
|
||||
/* profile specific decompression context structure */
|
||||
void *profile_context;
|
||||
}
|
||||
Iprohc_d_context;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Iprohc_decompressor
|
||||
*===========================================================================
|
||||
* This is the ROHC decompressor context structure
|
||||
*/
|
||||
|
||||
typedef struct Iprohc_decompressor_struct
|
||||
{
|
||||
|
||||
/* Context list */
|
||||
Ip_u16 context_num; /* number of contexts */
|
||||
Ipcom_list context_head;
|
||||
|
||||
/* interface the decompressor is associated with */
|
||||
struct Iprohc_interface *interface;
|
||||
|
||||
#ifdef IPROHC_ENABLE_REENTRANT
|
||||
Ipcom_mutex code_mutex; /* Mutex to protect compressor data. */
|
||||
#endif
|
||||
|
||||
#ifndef IP_PORT_VXWORKS /* for Linux recursive semaphore */
|
||||
/* the process that currently holds the semaphore and taken counter */
|
||||
Ip_pid_t pid;
|
||||
Ip_u8 s_counter;
|
||||
#endif /* !IP_PORT_VXWORKS */
|
||||
}
|
||||
Iprohc_decompressor;
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_PUBLIC Iprohc_decompressor * iprohc_alloc_decompressor(struct Iprohc_interface *interface);
|
||||
IP_PUBLIC Ip_err iprohc_del_decompressor(Iprohc_decompressor *decompressor);
|
||||
IP_PUBLIC Ip_err iprohc_d_del_profile_contexts(Iprohc_decompressor *decompressor, Ip_u8 profileid);
|
||||
|
||||
IP_PUBLIC Iprohc_d_context * iprohc_d_context_common_create(Ip_u16 cid);
|
||||
IP_PUBLIC Ip_err iprohc_d_context_common_del(Iprohc_d_context *d_context);
|
||||
IP_PUBLIC Ip_err iprohc_d_print_context(Iprohc_decompressor *decompressor, Ip_u8 profile);
|
||||
|
||||
/* Debug functions */
|
||||
IP_PUBLIC void iprohc_d_print_a_context(Iprohc_d_context *context);
|
||||
IP_PUBLIC char * iprohc_decomp_state(Iprohc_decomp_state state);
|
||||
IP_PUBLIC char * iprohc_decomp_trans(Iprohc_decomp_trans trans);
|
||||
|
||||
|
||||
#ifndef IP_PORT_VXWORKS /* for Linux recursive semaphore */
|
||||
|
||||
IP_PUBLIC void iprohc_decomp_lck(Iprohc_decompressor *decomp);
|
||||
IP_PUBLIC void iprohc_decomp_unlck(Iprohc_decompressor *decomp);
|
||||
|
||||
IP_PUBLIC void iprohc_d_context_lck(Iprohc_d_context *context);
|
||||
IP_PUBLIC void iprohc_d_context_unlck(Iprohc_d_context *context);
|
||||
|
||||
#endif /* !IP_PORT_VXWORKS */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /* #ifndef IPROHC_DECOMP_H */
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user