464 lines
13 KiB
C
464 lines
13 KiB
C
/* iprohc_comp.h - ROHC compressor 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
|
|
--------------------
|
|
01j,05Jul12,ggz Defect WIND00351290. Use ipcom_mutex_lock for unix port
|
|
01i,20oct11,ggz Fix for defect WIND00312450
|
|
01h,27mar10,ggz Resolve coverity warnings
|
|
01g,24feb09,tlu Replace ipcom_tmo by ipnet_timeout to port to LKM
|
|
01f,15jul08,tlu Add CID bit map fields
|
|
01e,17jun08,tlu Add functin to modify next context ID
|
|
01d,30may08,ggz Add Normal state for uncompressed profile
|
|
01c,12may08,tlu Add debugging utilities
|
|
01b,29apr08,tlu Add CRC validation for feedback with CRC option
|
|
01a,06mar08,tlu Created.
|
|
*/
|
|
|
|
#ifndef IPROHC_COMP_H
|
|
#define IPROHC_COMP_H
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#include <ipcom_tags.h>
|
|
#include <ipcom_type.h>
|
|
#include <ipcom_list.h>
|
|
#include <ipnet_timeout.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_COMP_LOCK(comp) ipcom_mutex_lock((comp)->code_mutex)
|
|
#define IPROHC_COMP_UNLOCK(comp) ipcom_mutex_unlock((comp)->code_mutex)
|
|
|
|
#define IPROHC_C_CONTEXT_LOCK(context) ipcom_mutex_lock((context)->code_mutex)
|
|
#define IPROHC_C_CONTEXT_UNLOCK(context) ipcom_mutex_unlock((context)->code_mutex)
|
|
|
|
#else /* NOTIP_PORT_VXWORKS, for linux recursive semaphore */
|
|
|
|
#define IPROHC_COMP_LOCK(comp) iprohc_comp_lck(comp)
|
|
#define IPROHC_COMP_UNLOCK(comp) iprohc_comp_unlck(comp)
|
|
|
|
#define IPROHC_C_CONTEXT_LOCK(context) iprohc_c_context_lck(context)
|
|
#define IPROHC_C_CONTEXT_UNLOCK(context) iprohc_c_context_unlck(context)
|
|
|
|
#endif /* IP_PORT_VXWORKS */
|
|
|
|
#else
|
|
|
|
#define IPROHC_COMP_LOCK(comp) IP_NOOP
|
|
#define IPROHC_COMP_UNLOCK(comp) IP_NOOP
|
|
|
|
#define IPROHC_C_CONTEXT_LOCK(context) IP_NOOP
|
|
#define IPROHC_C_CONTEXT_UNLOCK(context) IP_NOOP
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* IPROHC_ACK_FEEDBACK
|
|
*===========================================================================
|
|
* Process ACK feedback.
|
|
*/
|
|
#define IPROHC_ACK_FEEDBACK(context) \
|
|
{ \
|
|
if (context->state == ROHC_COMP_STATE_IR) \
|
|
{ \
|
|
if (context->trans == ROHC_COMP_TRANS_PENDING) \
|
|
{ \
|
|
context->state = ROHC_COMP_STATE_FO; \
|
|
} \
|
|
else \
|
|
{ \
|
|
context->state = ROHC_COMP_STATE_SO; \
|
|
context->pkt_type = ROHC_PKT_TYPE_0; \
|
|
context->ext_type = ROHC_EXT_NO_EXT; \
|
|
} \
|
|
} \
|
|
else if ((context->state == ROHC_COMP_STATE_FO) && \
|
|
(context->trans != ROHC_COMP_TRANS_PENDING)) \
|
|
{ \
|
|
context->state = ROHC_COMP_STATE_SO; \
|
|
context->pkt_type = ROHC_PKT_TYPE_0; \
|
|
context->ext_type = ROHC_EXT_NO_EXT; \
|
|
} \
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* IPROHC_PROCESS_FEEDBACK_OPT
|
|
*===========================================================================
|
|
* Process feedback options.
|
|
*/
|
|
#define IPROHC_PROCESS_FEEDBACK_OPT(context, feedback, pointer, size) \
|
|
{ \
|
|
Ip_u8 opt_type, cal_crc, opt_crc; \
|
|
\
|
|
while (pointer+1 <= size) \
|
|
{ \
|
|
opt_type = (feedback[pointer] & 0xF0) >> 4; \
|
|
switch (opt_type) \
|
|
{ \
|
|
case ROHC_FEEDBACK_OPT_CRC: \
|
|
/* CRC validation */ \
|
|
opt_crc = feedback[pointer+1]; \
|
|
feedback[pointer+1] = 0; \
|
|
cal_crc = iprohc_crc8((Ip_u8 *)feedback, size); \
|
|
if (cal_crc != opt_crc) \
|
|
{ /* Failed CRC validation, discard the feedback element */ \
|
|
IPROHC_C_CONTEXT_UNLOCK(context); \
|
|
return IPCOM_ERR_INVALID_PACKET; \
|
|
} \
|
|
pointer = (Ip_u8)(pointer + 2); \
|
|
break; \
|
|
case ROHC_FEEDBACK_OPT_REJ: \
|
|
/* Set up reject flag in context, not used */ \
|
|
context->reject = IP_TRUE; \
|
|
pointer ++; \
|
|
break; \
|
|
case ROHC_FEEDBACK_OPT_SN_NOT_VALID: \
|
|
/* Not using SN in feedback currently */ \
|
|
pointer ++; \
|
|
break; \
|
|
case ROHC_FEEDBACK_OPT_SN: \
|
|
/* Not using SN in feedback currently */ \
|
|
pointer = (Ip_u8)(pointer + 2); \
|
|
break; \
|
|
case ROHC_FEEDBACK_OPT_LOSS: \
|
|
/* Not used */ \
|
|
pointer = (Ip_u8)(pointer + 2); \
|
|
break; \
|
|
case ROHC_FEEDBACK_OPT_CONTEXT_MEMORY: \
|
|
/* Not used */ \
|
|
pointer ++; \
|
|
break; \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* IPROHC_PROCESS_MODE
|
|
*===========================================================================
|
|
* Process mode field from feedback.
|
|
*/
|
|
#define IPROHC_PROCESS_MODE(context, mode) \
|
|
{ \
|
|
if (context->mode == mode) \
|
|
{ \
|
|
if (context->trans == ROHC_COMP_TRANS_PENDING) \
|
|
{ \
|
|
context->trans = ROHC_COMP_TRANS_DONE; \
|
|
context->decline_mode_trans = IP_FALSE; \
|
|
} \
|
|
} \
|
|
else \
|
|
{ \
|
|
if (context->trans == ROHC_COMP_TRANS_PENDING) \
|
|
{ \
|
|
context->decline_mode_trans = IP_TRUE; \
|
|
} \
|
|
else \
|
|
{ \
|
|
context->trans = ROHC_COMP_TRANS_PENDING; \
|
|
context->mode = mode; \
|
|
} \
|
|
context->pkt_type = ROHC_PKT_TYPE_2; \
|
|
context->ext_type = ROHC_EXT_3; \
|
|
} \
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* IPROHC_PROCESS_ACKTYPE
|
|
*===========================================================================
|
|
* Process acktype field from feedback.
|
|
*/
|
|
#define IPROHC_PROCESS_ACKTYPE(context, acktype) \
|
|
{ \
|
|
if (acktype == ROHC_FEEDBACK_ACK) \
|
|
{ \
|
|
IPROHC_ACK_FEEDBACK(context); \
|
|
} \
|
|
else if (acktype == ROHC_FEEDBACK_NACK) \
|
|
{ \
|
|
if (context->state == ROHC_COMP_STATE_SO) \
|
|
context->state = ROHC_COMP_STATE_FO; \
|
|
context->pkt_type = ROHC_PKT_IR_DYN; \
|
|
context->ext_type = ROHC_EXT_NO_EXT; \
|
|
} \
|
|
else if (acktype == ROHC_FEEDBACK_STATIC_NACK) \
|
|
{ \
|
|
context->state = ROHC_COMP_STATE_IR; \
|
|
context->pkt_type = ROHC_PKT_IR; \
|
|
context->ext_type = ROHC_EXT_NO_EXT; \
|
|
context->num_ir = 0; \
|
|
} \
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Compressor states
|
|
*===========================================================================
|
|
* refer to RFC 3095, section 4.3.1
|
|
*/
|
|
|
|
typedef enum
|
|
{
|
|
ROHC_COMP_STATE_IR = 1,
|
|
ROHC_COMP_STATE_FO,
|
|
ROHC_COMP_STATE_SO,
|
|
ROHC_COMP_STATE_NORMAL
|
|
} Iprohc_comp_state;
|
|
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Compressor mode transitions
|
|
*===========================================================================
|
|
* refer to RFC 3095, section 5.6.1
|
|
*/
|
|
|
|
typedef enum
|
|
{
|
|
ROHC_COMP_TRANS_DONE = 0,
|
|
ROHC_COMP_TRANS_PENDING
|
|
} Iprohc_comp_trans;
|
|
|
|
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* Public TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* LOCAL TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
struct Iprohc_compressor;
|
|
struct Iprohc_interface;
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Iprohc_c_context
|
|
*===========================================================================
|
|
* This is the ROHC compression context structure
|
|
*/
|
|
|
|
typedef struct Iprohc_c_context_struct
|
|
{
|
|
Ipcom_list context_list;
|
|
|
|
/* CID allocated for the context */
|
|
Ip_u16 cid;
|
|
|
|
/* compression state */
|
|
Iprohc_comp_state state;
|
|
|
|
/* compression mode */
|
|
Iprohc_mode mode;
|
|
|
|
/* Decline mode transition, RFC 3843, section 3.4 */
|
|
Ip_bool decline_mode_trans;
|
|
|
|
/* compression mode transition */
|
|
Iprohc_comp_trans trans;
|
|
|
|
/* to-be-transmitted compression packet type */
|
|
Ip_u8 pkt_type;
|
|
|
|
/* to-be-transmitted entension type */
|
|
Iprohc_extension ext_type;
|
|
|
|
/* Whether received reject option from feedback */
|
|
Ip_bool reject;
|
|
|
|
/* number of consecutively transmitted IR packets */
|
|
Ip_u32 num_ir;
|
|
|
|
/* number of consecutively transmitted compressed packets */
|
|
Ip_u32 num_compressed;
|
|
|
|
/* stream type: IPv4 or IPv6, for feedback processing */
|
|
Ip_u8 stream_type;
|
|
|
|
/* destination address of the stream, for feedback processing */
|
|
Iprohc_addr dst;
|
|
|
|
/* source address of the stream */
|
|
Iprohc_addr src;
|
|
|
|
/* profile the compressor is associated with */
|
|
Ip_u8 profileid;
|
|
|
|
/* Compressor the context is associated with */
|
|
struct Iprohc_compressor *compressor;
|
|
|
|
/* maximum consecutive compressed header timer: F_MAX_TIME timer */
|
|
Ipnet_timeout *retx_ir;
|
|
|
|
|
|
#ifdef IPROHC_ENABLE_REENTRANT
|
|
Ipcom_mutex code_mutex; /* Mutex to protect context 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 compression context structure */
|
|
void *profile_context;
|
|
}
|
|
Iprohc_c_context;
|
|
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Iprohc_compressor
|
|
*===========================================================================
|
|
* This is the ROHC compressor context structure
|
|
*/
|
|
|
|
typedef struct Iprohc_compressor_struct
|
|
{
|
|
/* record the next to be used CID */
|
|
Ip_u16 to_be_used_cid;
|
|
|
|
/* Context list */
|
|
Ip_u16 context_num; /* number of contexts */
|
|
Ipcom_list context_head;
|
|
|
|
/* interface the compressor is associated with */
|
|
struct Iprohc_interface *interface;
|
|
|
|
/* bit map to record whether a CID is allocated */
|
|
Ip_u16 *cid_bit_map;
|
|
Ip_u16 bit_map_size;
|
|
|
|
#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_compressor;
|
|
|
|
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* GLOBAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_PUBLIC Iprohc_compressor * iprohc_alloc_compressor(struct Iprohc_interface *interface);
|
|
IP_PUBLIC Ip_err iprohc_del_compressor(Iprohc_compressor *compressor);
|
|
IP_PUBLIC Ip_err iprohc_c_del_profile_contexts(Iprohc_compressor *compressor, Ip_u8 profileid);
|
|
IP_PUBLIC Ip_err iprohc_comp_mod_cid(struct Iprohc_interface *interface,
|
|
Ip_u8 profileid, Ip_u16 cid);
|
|
|
|
IP_PUBLIC Iprohc_c_context * iprohc_c_context_common_create(Ip_u16 cid);
|
|
IP_PUBLIC Ip_err iprohc_c_context_common_del(Iprohc_c_context *c_context);
|
|
IP_PUBLIC Ip_err iprohc_c_process_feedback(Iprohc_compressor *compressor,
|
|
Ip_u8 src_addr_type,
|
|
void *src_addr,
|
|
Ip_u16 feedback_num,
|
|
Ip_u8 *feedbacks);
|
|
IP_PUBLIC void iprohc_retx_ir_timeout(void *cookie);
|
|
|
|
IP_PUBLIC Ip_err iprohc_c_print_context(Iprohc_compressor *compressor, Ip_u8 profile);
|
|
|
|
/* Debug functions */
|
|
IP_PUBLIC void iprohc_c_print_a_context(Iprohc_c_context *context);
|
|
IP_PUBLIC char * iprohc_comp_state(Iprohc_comp_state state);
|
|
IP_PUBLIC char * iprohc_comp_trans(Iprohc_comp_trans trans);
|
|
|
|
|
|
#ifndef IP_PORT_VXWORKS /* for Linux recursive semaphore */
|
|
|
|
IP_PUBLIC void iprohc_comp_lck(Iprohc_compressor *comp);
|
|
IP_PUBLIC void iprohc_comp_unlck(Iprohc_compressor *comp);
|
|
|
|
IP_PUBLIC void iprohc_c_context_lck(Iprohc_c_context *context);
|
|
IP_PUBLIC void iprohc_c_context_unlck(Iprohc_c_context *context);
|
|
|
|
#endif /* !IP_PORT_VXWORKS */
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
#endif /* #ifndef IPROHC_COMP_H */
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|
|
|