// Calculate the size of data in an IR-package. // return : size or zero. int uncompressed_detect_ir_size(unsigned char * first_byte, int second_byte_add) { int ret = 10; int d = GET_BIT_0(first_byte); if (d) ret += 5 + 2; if (first_byte[second_byte_add + 2] != 0x40) return 0; return ret; }
/** * @brief Get the bit in the given byte at the given position * * @param byte The byte to analyse * @param pos The position between 0 and 7 * @return The requested bit */ static uint8_t rohc_get_bit(const unsigned char byte, const size_t pos) { uint8_t bit; switch(pos) { case 0: bit = GET_REAL(GET_BIT_0(&byte)); break; case 1: bit = GET_REAL(GET_BIT_1(&byte)); break; case 2: bit = GET_REAL(GET_BIT_2(&byte)); break; case 3: bit = GET_REAL(GET_BIT_3(&byte)); break; case 4: bit = GET_REAL(GET_BIT_4(&byte)); break; case 5: bit = GET_REAL(GET_BIT_5(&byte)); break; case 6: bit = GET_REAL(GET_BIT_6(&byte)); break; case 7: bit = GET_REAL(GET_BIT_7(&byte)); break; default: /* there is no such bit in a byte */ assert(0); /* should not happen */ bit = 0; break; } return bit; }
//---------------------------------------------------------------------------------------------------------------------------------- // Main function for decompressing a ROHC-packet. // Param state: pointer to decompressor // Param ibuf: pointer to incoming packet // Param isize: size of incoming packet // Param obuf: pointer to output buffer // Param osize: size of output buffer // Param ddata: struct that holds important information to pass between several functions // Return: size of decompressed packet //---------------------------------------------------------------------------------------------------------------------------------- int d_decode_header(struct sd_rohc * state, unsigned char * ibuf, int isize, unsigned char * obuf, int osize, struct sd_decode_data * ddata) { int largecid=0, size, irdynvar=0, casenew=0; struct s_profile * profile; unsigned char * walk = ibuf; if(isize < 2) return(ROHC_ERROR_NO_CONTEXT); ddata->cid = d_decode_feedback_first(state, &walk, isize); if(ddata->cid == ROHC_FEEDBACK_ONLY || ddata->cid == ROHC_ERROR_NO_CONTEXT) return(ddata->cid); if(ddata->cid > 0 && state->medium->cid_type == ROHC_SMALL_CID) ddata->addcidUsed=1; if(!ddata->addcidUsed && state->medium->cid_type == ROHC_LARGE_CID) { // check if large cids are used largecid = d_sdvalue_size(walk+1); if(largecid >0 && largecid < 3) { ddata->cid = d_sdvalue_decode(walk+1); ddata->largecidUsed=1; } else return(ROHC_ERROR_NO_CONTEXT); } if(d_is_ir(walk)) { profile = find_profile(walk[largecid+1]); if(!rohc_ir_packet_crc_ok(walk, largecid, ddata->addcidUsed, profile)) return(ROHC_ERROR_CRC); if(ddata->cid >= state->context_array_size) context_array_increase(state, ddata->cid); if(state->context[ddata->cid] && state->context[ddata->cid]->profile == profile) { ddata->active = state->context[ddata->cid]; state->context[ddata->cid] = NULL; } else { casenew=1; ddata->active = context_create(state, ddata->cid, profile); if(!ddata->active) return(ROHC_ERROR_NO_CONTEXT); } ddata->active->num_recv_ir ++; size = ddata->active->profile->decode_ir(state, ddata->active, walk+largecid+3, (isize-(walk-ibuf))-3-largecid, GET_BIT_0(walk), obuf); if(size>0) { context_free(state->context[ddata->cid]); state->context[ddata->cid] = ddata->active; return(size); } if(casenew) context_free(ddata->active); else state->context[ddata->cid] = ddata->active; return(size); } else { ddata->active = find_context(state, ddata->cid); // find context if(ddata->active && ddata->active->profile) { // context is valid ddata->active->latest_used = get_milliseconds(); if(d_is_irdyn(walk)) { ddata->active->num_recv_ir_dyn ++; profile = find_profile(walk[largecid+1]); if(profile != ddata->active->profile) { // if IR-DYN changes profile, make comp. transit to NO_CONTEXT-state state->curval = state->maxval; rohc_debugf(2,"IR-DYN changed profile, sending S-NACK.\n"); return(ROHC_ERROR_NO_CONTEXT); } if(!rohc_ir_dyn_packet_crc_ok(walk, largecid, ddata->addcidUsed, profile, ddata->active)) return(ROHC_ERROR_CRC); irdynvar += 2; } return(ddata->active->profile->decode(state, ddata->active, walk, (isize-(walk-ibuf)), (ddata->largecidUsed ? (1+largecid+irdynvar) : 1+irdynvar), obuf)); } else return(ROHC_ERROR_NO_CONTEXT); } return(ROHC_ERROR_NO_CONTEXT); }