/* 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 #include #include #include #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 **************************************************************************** */