コード例 #1
0
ファイル: decomp_list.c プロジェクト: rafaelcoelho/rohc
/**
 * @brief Decode an extension list type 3
 *
 * @param decomp      The list decompressor
 * @param packet      The ROHC packet to decompress
 * @param packet_len  The length (in bytes) of the packet to decompress
 * @param gen_id      The id of the current list
 *                    maybe ROHC_LIST_GEN_ID_ANON if not defined
 * @param ps          The ps field
 * @param xi_1        The XI 1 field if PS = 1 (4-bit XI)
 * @return            \li In case of success, the number of bytes read in the given
 *                        packet, ie. the length of the compressed list
 *                    \li -1 in case of failure
 */
static int rohc_list_decode_type_3(struct list_decomp *const decomp,
                                   const uint8_t *packet,
                                   size_t packet_len,
                                   const unsigned int gen_id,
                                   const int ps,
                                   const int xi_1)
{
	size_t packet_read_len = 0;
	struct rohc_list removal_list; /* list after removal scheme but before insertion scheme */
	unsigned int ref_id;
	int ret;

	assert(decomp != NULL);
	assert(packet != NULL);
	assert(gen_id != ROHC_LIST_GEN_ID_NONE);
	assert(ps == 0 || ps == 1);

	/* in case of 8-bit XI, the XI 1 field should be set to 0 */
	if(ps && xi_1 != 0)
	{
		rd_list_warn(decomp, "sender does not conform to ROHC standards: when "
		             "8-bit XIs are used, the 4-bit XI 1 field should be set "
		             "to 0, not 0x%x", xi_1);
#ifdef ROHC_RFC_STRICT_DECOMPRESSOR
		goto error;
#endif
	}

	/* is there enough data in packet for the ref_id? */
	if(packet_len < 1)
	{
		rd_list_warn(decomp, "packet too small for ref_id and minimal removal "
		             "bit mask fields (only %zu bytes while at least 1 byte "
		             "is required)", packet_len);
		goto error;
	}

	/* parse ref_id */
	ref_id = GET_BIT_0_7(packet);
	packet++;
	packet_len--;
	packet_read_len++;
	rd_list_debug(decomp, "ref_id = 0x%02x", ref_id);
	/* reference list must be known */
	if(!rohc_list_is_gen_id_known(decomp, ref_id))
	{
		rd_list_warn(decomp, "unknown ID 0x%02x given for reference list",
		             ref_id);
		goto error;
	}
	/* reference list must not be empty (RFC 4815, §5.7) */
	if(decomp->lists[ref_id].items_nr == 0)
	{
		rd_list_warn(decomp, "list encoding type 3 must not be used with an "
		             "empty reference list, discard packet");
		goto error;
	}

	/* removal scheme */
	rohc_list_reset(&removal_list);
	ret = rohc_list_parse_removal_scheme(decomp, packet, packet_len,
	                                     &(decomp->lists[ref_id]), &removal_list);
	if(ret < 0)
	{
		if(gen_id == ROHC_LIST_GEN_ID_ANON)
		{
			rd_list_warn(decomp, "failed to anonymous decompress list based on "
			             "reference list %u: removal scheme failed", ref_id);
		}
		else
		{
			rd_list_warn(decomp, "failed to decompress list with ID %u based on "
			             "reference list %u: removal scheme failed", gen_id, ref_id);
		}
		goto error;
	}
	packet += ret;
	packet_len -= ret;
	packet_read_len += ret;

	/* insertion scheme */
	ret = rohc_list_parse_insertion_scheme(decomp, packet, packet_len, ps, xi_1,
	                                       removal_list.items_nr, &removal_list,
	                                       &decomp->pkt_list);
	if(ret < 0)
	{
		if(gen_id == ROHC_LIST_GEN_ID_ANON)
		{
			rd_list_warn(decomp, "failed to anonymous decompress list based on "
			             "reference list %u: removal scheme failed", ref_id);
		}
		else
		{
			rd_list_warn(decomp, "failed to decompress list with ID %u based on "
			             "reference list %u: insertion scheme failed", gen_id, ref_id);
		}
		goto error;
	}
#ifndef __clang_analyzer__ /* silent warning about dead in/decrement */
	packet += ret;
	packet_len -= ret;
#endif
	packet_read_len += ret;

	return packet_read_len;

error:
	return -1;
}
コード例 #2
0
ファイル: decomp_list.c プロジェクト: b12mihai/rohc
/**
 * @brief Decompress the compressed list in given packet
 *
 * @param decomp      The list decompressor
 * @param packet      The ROHC packet to decompress
 * @param packet_len  The remaining length of the packet to decode (in bytes)
 * @return            The size of the compressed list in packet in case of
 *                    success, -1 in case of failure
 */
static int rohc_list_decode(struct list_decomp *decomp,
                            const uint8_t *packet,
                            size_t packet_len)
{
	size_t read_length = 0;
	uint8_t et;    /* the type of list encoding */
	bool gp;       /* whether the gen_id field is present or not */
	uint8_t ps;    /* the type of XI field */
	uint8_t m;     /* the CC or Count field (share bits with XI 1) */
	uint8_t xi_1;  /* the XI 1 field (share bits with m) */
	unsigned int gen_id; /* the gen_id if present,
	                        ROHC_LIST_GEN_ID_ANON otherwise */
	int ret;

	/* reset the list of the current packet */
	rohc_list_reset(&decomp->pkt_list);

	/* is there enough data in packet for the ET, PS, m/XI1 and gen_id
	 * fields? */
	if(packet_len < 2)
	{
		rd_list_warn(decomp, "packet too small for compressed list (only %zu "
		             "bytes while at least 2 bytes are required)", packet_len);
		goto error;
	}

	/* parse ET, GP, PS, and m/XI1 fields */
	et = GET_BIT_6_7(packet);
	gp = !!GET_BIT_5(packet);
	ps = GET_REAL(GET_BIT_4(packet));
	m = GET_BIT_0_3(packet);
	xi_1 = m; /* m and XI 1 are the same field */
	packet++;
	read_length++;
	packet_len--;
	rd_list_debug(decomp, "ET = %d, GP = %d, PS = %d, m = XI 1 = %d",
	              et, gp, ps, m);
	assert(m <= ROHC_LIST_ITEMS_MAX);

	/* parse gen_id if present */
	if(gp == 1)
	{
		gen_id = GET_BIT_0_7(packet);
		packet++;
		read_length++;
		packet_len--;
		rd_list_debug(decomp, "gen_id = 0x%02x", gen_id);
	}
	else
	{
		gen_id = ROHC_LIST_GEN_ID_ANON;
		rd_list_debug(decomp, "decode anonymous list");
	}
	decomp->pkt_list.id = gen_id;

	/* decode the compressed list according to its type */
	switch(et)
	{
		case 0:
			ret = rohc_list_decode_type_0(decomp, packet, packet_len,
			                              gen_id, ps, m);
			break;
		case 1:
			ret = rohc_list_decode_type_1(decomp, packet, packet_len,
			                              gen_id, ps, xi_1);
			break;
		case 2:
			ret = rohc_list_decode_type_2(decomp, packet, packet_len, gen_id);
			break;
		case 3:
			ret = rohc_list_decode_type_3(decomp, packet, packet_len,
			                              gen_id, ps, xi_1);
			break;
		default:
			/* should not happen */
			rohc_error(decomp, ROHC_TRACE_DECOMP, decomp->profile_id,
			           "unknown type of compressed list (ET = %u)", et);
			assert(0);
			goto error;
	}
	if(ret < 0)
	{
		rd_list_warn(decomp, "failed to decode compressed list type %d", et);
		goto error;
	}
	assert(((size_t) ret) <= packet_len);
#ifndef __clang_analyzer__ /* silent warning about dead in/decrement */
	packet += ret;
	packet_len -= ret;
#endif
	read_length += ret;

	/* RFC3095, section 5.8.2.1 reads:
	 *   When the decompressor receives a compressed list, it retrieves the
	 *   proper ref_list from the sliding window based on the ref_id, and
	 *   decompresses the compressed list obtaining curr_list.
	 *   In U/O-mode, curr_list is inserted into the sliding window
	 *   together with its generation identifier if the compressed list had
	 *   a generation identifier and the sliding window does not contain a
	 *   list with that generation identifier.  All lists with generations
	 *   older than ref_id are removed from the sliding window. */
	if(gen_id == ROHC_LIST_GEN_ID_ANON)
	{
		/* list is not identified by a gen_id, so do not update the sliding
		 * window of lists */
		rd_list_debug(decomp, "anonymous list was received");
	}
	else if(decomp->lists[gen_id].counter > 0)
	{
		/* list is identified by a gen_id, but the sliding window of lists
		 * already contain a list with that generation identifier, so do
		 * not update the sliding window of lists */
		decomp->lists[gen_id].counter++;
		rd_list_debug(decomp, "list with gen_id %u is already present in "
		              "reference lists (received for the #%zu times)",
		              gen_id, decomp->lists[gen_id].counter);
	}
	else
	{
		/* list is identified by a gen_id and the sliding window of lists does
		 * not contain a list with that generation identifier yet, so update
		 * the sliding window of lists */
		rd_list_debug(decomp, "list with gen_id %u is not present yet in "
		              "reference lists, add it", gen_id);
		memcpy(decomp->lists[gen_id].items, decomp->pkt_list.items,
		       ROHC_LIST_ITEMS_MAX * sizeof(struct decomp_list *));
		decomp->lists[gen_id].items_nr = decomp->pkt_list.items_nr;
		decomp->lists[gen_id].counter = 1;
		/* TODO: remove all lists with gen_id < ref_id */
	}

	return read_length;

error:
	return -1;
}
コード例 #3
0
ファイル: decomp_list.c プロジェクト: rafaelcoelho/rohc
/**
 * @brief Decode an extension list type 2
 *
 * @param decomp      The list decompressor
 * @param packet      The ROHC packet to decompress
 * @param packet_len  The length (in bytes) of the packet to decompress
 * @param gen_id      The id of the current list,
 *                    maybe ROHC_LIST_GEN_ID_ANON if not defined
 * @return            \li In case of success, the number of bytes read in the given
 *                        packet, ie. the length of the compressed list
 *                    \li -1 in case of failure
 */
static int rohc_list_decode_type_2(struct list_decomp *const decomp,
                                   const uint8_t *packet,
                                   size_t packet_len,
                                   const unsigned int gen_id)
{
	size_t packet_read_len = 0;
	unsigned int ref_id;
	int ret;

	assert(decomp != NULL);
	assert(packet != NULL);
	assert(gen_id != ROHC_LIST_GEN_ID_NONE);

	/* is there enough data in packet for the ref_id and minimal removal
	   bit mask fields ? */
	if(packet_len < 2)
	{
		rd_list_warn(decomp, "packet too small for ref_id and minimal removal "
		             "bit mask fields (only %zu bytes while at least 2 bytes "
		             "are required)", packet_len);
		goto error;
	}

	/* parse ref_id */
	ref_id = GET_BIT_0_7(packet);
	packet++;
	packet_len--;
	packet_read_len++;
	rd_list_debug(decomp, "ref_id = 0x%02x", ref_id);
	/* reference list must be known */
	if(!rohc_list_is_gen_id_known(decomp, ref_id))
	{
		rd_list_warn(decomp, "unknown ID 0x%02x given for reference list",
		             ref_id);
		goto error;
	}
	/* reference list must not be empty (RFC 4815, §5.7) */
	if(decomp->lists[ref_id].items_nr == 0)
	{
		rd_list_warn(decomp, "list encoding type 2 must not be used with an "
		             "empty reference list, discard packet");
		goto error;
	}

	/* removal scheme */
	ret = rohc_list_parse_removal_scheme(decomp, packet, packet_len,
	                                     &(decomp->lists[ref_id]),
	                                     &(decomp->pkt_list));
	if(ret < 0)
	{
		if(gen_id == ROHC_LIST_GEN_ID_ANON)
		{
			rd_list_warn(decomp, "failed to anonymous decompress list based on "
			             "reference list %u: removal scheme failed", ref_id);
		}
		else
		{
			rd_list_warn(decomp, "failed to decompress list with ID %u based on "
			             "reference list %u: removal scheme failed", gen_id, ref_id);
		}
		goto error;
	}
#ifndef __clang_analyzer__ /* silent warning about dead in/decrement */
	packet += ret;
	packet_len -= ret;
#endif
	packet_read_len += ret;

	return packet_read_len;

error:
	return -1;
}
コード例 #4
0
ファイル: d_util.c プロジェクト: whoi-acomms/umodemd
// Decide if the field is a padding field
// Return: 1 = padding
//	   0 = else
int d_is_paddning(const unsigned char *data)
{
	if (GET_BIT_0_7(data) == D_PADDING)
		return 1;
	return 0;
}
コード例 #5
0
/****************************************************************************
*
*  Function Name    : FlashEraseSector
*  Description      : Perform erase operation on Flash
*  Arguments        : PFLASH_SSD_CONFIG, UINT32, UINT32, pFLASHCOMMANDSEQUENCE
*  Return Value     : UINT32
*
*****************************************************************************/
UINT32 FlashEraseSector(PFLASH_SSD_CONFIG pSSDConfig, \
                                  UINT32 dest, \
                                  UINT32 size, \
                                  pFLASHCOMMANDSEQUENCE pFlashCommandSequence)                                                                    
{
 
    UINT32 ret;      /* return code variable */
    UINT32 sectorSize ,temp;        /* size of one sector */
    ret = FTFx_OK;
    /* convert to byte address */
    dest = WORD2BYTE(dest);
    
#if (DEBLOCK_SIZE)
    temp = WORD2BYTE(pSSDConfig->DFlashBlockBase);
    if((dest >= temp) && (dest < (temp + pSSDConfig->DFlashBlockSize)))
    {
        dest = dest - temp + 0x800000;
        sectorSize = FTFx_DSECTOR_SIZE;
    }  
    else             
#endif
    {
        temp = WORD2BYTE(pSSDConfig->PFlashBlockBase);
        if((dest >= temp) && (dest < (temp + pSSDConfig->PFlashBlockSize)))    
        {
            dest -= temp;
            sectorSize = FTFx_PSECTOR_SIZE;
        }else{
            ret = FTFx_ERR_ACCERR;
            goto EXIT;
        }
    }      
     
    /* check if the size is sector alignment or not */
    if(size & (sectorSize-1))
    {
        /* return an error code FTFx_ERR_SIZE */
        ret = FTFx_ERR_SIZE;
        goto EXIT;
    }
  
    while(size > 0)
    {
       /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear*/
        REG_WRITE(pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET,FTFx_SSD_FSTAT_ERROR_BITS);   
        /* passing parameter to the command */
        REG_WRITE(pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET, FTFx_ERASE_SECTOR);
        REG_WRITE(pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET, GET_BIT_16_23(dest));
        REG_WRITE(pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB2_OFFSET, GET_BIT_8_15(dest));
        REG_WRITE(pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB3_OFFSET, GET_BIT_0_7(dest));

       /* calling flash command sequence function to execute the command */
        ret = pFlashCommandSequence(pSSDConfig);
            
        /* checking the success of command execution */
        if(FTFx_OK != ret)
        {
            break;
        }
        else
        {
            /* update size and destination address */
            size -= sectorSize;
            dest += sectorSize;
        }
    }

EXIT:
    /* Enter Debug state if enabled */
    if (TRUE == (pSSDConfig->DebugEnable))
    {
        ENTER_DEBUG_MODE;
    }

    return(ret);
}
コード例 #6
0
uint32_t SIZE_OPTIMIZATION FlashReadResource(PFLASH_SSD_CONFIG pSSDConfig, \
                                                uint32_t dest, \
                                                uint8_t* pDataArray, \
                                                uint8_t  resourceSelectCode, \
                                                pFLASHCOMMANDSEQUENCE pFlashCommandSequence)
{
    uint8_t i;
    uint32_t ret = FTFx_OK;       /* return code variable */
    uint32_t temp;

      /* convert to byte address */
    dest = WORD2BYTE(dest);
    /* check if the destination is aligned or not */
#if (DEBLOCK_SIZE)
    temp = WORD2BYTE(pSSDConfig->DFlashBase);
    if((dest >= temp) && (dest < (temp + pSSDConfig->DFlashSize)))
    {
        dest = dest - temp + 0x800000U;
    }
    else
#endif
    {
        temp = WORD2BYTE(pSSDConfig->PFlashBase);
        if((dest >= temp) && (dest < (temp + pSSDConfig->PFlashSize)))
        {
            dest -= temp;
        }
        else
        {
            ret = FTFx_ERR_ACCERR;
        }
    }
    if(ret == FTFx_OK)
    {
       /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear */
        temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET;
        REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS);

        /* passing parameter to the command */
        temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET;
        REG_WRITE(temp, FTFx_READ_RESOURCE);
        temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET;
        REG_WRITE(temp, GET_BIT_16_23(dest));
        temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB2_OFFSET;
        REG_WRITE(temp, GET_BIT_8_15(dest));
        temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB3_OFFSET;
        REG_WRITE(temp, GET_BIT_0_7(dest));

        temp = pSSDConfig->ftfxRegBase + RSRC_CODE_OFSSET;
        REG_WRITE(temp, resourceSelectCode);

        /* calling flash command sequence function to execute the command */
        ret = pFlashCommandSequence(pSSDConfig);

        if (FTFx_OK == ret)
        {
            /* Read the data from the FCCOB registers into the pDataArray */
            for (i = 0x0U; i < PGM_SIZE_BYTE; i ++)
            {
                temp = pSSDConfig->ftfxRegBase + i + 0x08U;
                pDataArray[i] = REG_READ(temp);
            }
        }
    }
#if C90TFS_ENABLE_DEBUG
    /* Enter Debug state if enabled */
    if (TRUE == (pSSDConfig->DebugEnable))
    {
        ENTER_DEBUG_MODE;
    }
#endif

    return(ret);
}
コード例 #7
0
uint32_t SIZE_OPTIMIZATION FlashProgramSection(PFLASH_SSD_CONFIG pSSDConfig, \
                                                uint32_t dest, \
                                                uint16_t number, \
                                                pFLASHCOMMANDSEQUENCE pFlashCommandSequence)
{

    uint32_t ret = FTFx_OK;      /* return code variable */
    uint32_t temp;

    /* check RAMRDY bit of the flash configuration register */
    temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCNFG_OFFSET;
    if(0x0U == (REG_BIT_GET(temp, FTFx_SSD_FCNFG_RAMRDY)))
    {
        /* return an error code FTFx_ERR_RAMRDY */
        ret = FTFx_ERR_RAMRDY;
    }
    else
    {
        /* convert to byte address */
        dest = WORD2BYTE(dest);
#if (DEBLOCK_SIZE)
        temp = WORD2BYTE(pSSDConfig->DFlashBase);
        if((dest >= temp) && (dest < (temp + pSSDConfig->DFlashSize)))
        {
            dest = dest - temp + 0x800000U;
        }
        else
#endif
        {
            temp = WORD2BYTE(pSSDConfig->PFlashBase);
            if((dest >= temp) && (dest < (temp + pSSDConfig->PFlashSize)))
            {
                dest -= temp;
            }
            else
            {
                ret = FTFx_ERR_ACCERR;
            }
        }

        if(ret == FTFx_OK)
        {
            temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET;
            REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS);

            /* passing parameter to command */
            temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET;
            REG_WRITE(temp, FTFx_PROGRAM_SECTION);

            temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET;
            REG_WRITE(temp, GET_BIT_16_23(dest));

            temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB2_OFFSET;
            REG_WRITE(temp, GET_BIT_8_15(dest));

            temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB3_OFFSET;
            REG_WRITE(temp, GET_BIT_0_7(dest));

            temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB4_OFFSET;
            REG_WRITE(temp, GET_BIT_8_15(number));

            temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET;
            REG_WRITE(temp, GET_BIT_0_7(number));

            /* calling flash command sequence function to execute the command */
            ret = pFlashCommandSequence(pSSDConfig);
        }
    }

#if C90TFS_ENABLE_DEBUG
    /* Enter Debug state if enabled */
    if (TRUE == (pSSDConfig->DebugEnable))
    {
        ENTER_DEBUG_MODE;
    }
#endif

    return(ret);
}