Beispiel #1
0
// 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;
}
Beispiel #2
0
/**
 * @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;
}
Beispiel #3
0
//----------------------------------------------------------------------------------------------------------------------------------
// 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);
}