Merge branch 'develop' into RU-RAU-split
Conflicts: openair1/PHY/INIT/lte_init.c openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c openair1/PHY/LTE_TRANSPORT/dci.c openair1/PHY/LTE_TRANSPORT/dci_tools.c openair1/PHY/LTE_TRANSPORT/dlsch_coding.c openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c openair1/PHY/LTE_TRANSPORT/if4_tools.c openair1/PHY/LTE_TRANSPORT/if5_tools.c openair1/PHY/LTE_TRANSPORT/if5_tools.h openair1/PHY/LTE_TRANSPORT/pcfich.c openair1/PHY/LTE_TRANSPORT/phich.c openair1/PHY/LTE_TRANSPORT/prach.c openair1/PHY/LTE_TRANSPORT/rar_tools.c openair1/PHY/LTE_TRANSPORT/srs_modulation.c openair1/PHY/defs.h openair1/PHY/impl_defs_lte.h openair1/PHY/impl_defs_top.h openair1/SCHED/phy_procedures_lte_eNb.c openair1/SCHED/phy_procedures_lte_ue.c openair2/COMMON/mac_rrc_primitives.h openair2/ENB_APP/enb_config.c openair2/ENB_APP/enb_config.h openair2/LAYER2/MAC/config.c openair2/LAYER2/MAC/eNB_scheduler.c openair2/LAYER2/MAC/eNB_scheduler_dlsch.c openair2/LAYER2/MAC/eNB_scheduler_mch.c openair2/LAYER2/MAC/eNB_scheduler_primitives.c openair2/LAYER2/MAC/main.c openair2/LAYER2/MAC/proto.h openair2/RRC/LITE/MESSAGES/asn1_msg.c openair2/RRC/LITE/MESSAGES/asn1_msg.h openair2/RRC/LITE/rrc_UE.c openair2/RRC/LITE/rrc_common.c openair2/RRC/LITE/rrc_eNB.c targets/ARCH/COMMON/common_lib.c targets/ARCH/COMMON/common_lib.h targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.25PRB.lo.conf targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.25PRB.oaisim.conf targets/RT/USER/lte-enb.c targets/RT/USER/lte-softmodem.c targets/RT/USER/lte-ue.c targets/RT/USER/rt_wrapper.h targets/SIMU/USER/channel_sim.c targets/SIMU/USER/init_lte.c targets/SIMU/USER/oaisim.c targets/SIMU/USER/oaisim_functions.c
This commit is contained in:
@@ -1,59 +0,0 @@
|
||||
export KERNEL_DIR=/lib/modules/$(shell uname -r)/
|
||||
CC=gcc
|
||||
CCC=gcc
|
||||
linux := $(shell if [ `uname` = "Linux" ] ; then echo "1" ; else echo "0" ; fi)
|
||||
|
||||
|
||||
CFLAGS += -std=gnu99
|
||||
CFLAGS += -Wall -g -ggdb -Wstrict-prototypes -fno-strict-aliasing
|
||||
|
||||
# Need to force this option because default kernel module builder is wrong
|
||||
CFLAGS += $(call cc-option,-mpreferred-stack-boundary=4)
|
||||
|
||||
#For performance, if some option doesn't exist in all gcc versions, use $(call cc-option,MY_OPTION)
|
||||
#CFLAGS += -O2
|
||||
#CFLAGS += -funroll-loops
|
||||
CFLAGS += -Wno-packed-bitfield-compat
|
||||
|
||||
# This is the minimum CPU faetures for OAI
|
||||
CFLAGS += -mmmx -msse -msse2 -mssse3 -msse4.1
|
||||
# Add CPU features from local CPU
|
||||
#CFLAGS += -march=native
|
||||
|
||||
ifeq ($(OSTYPE),Cygwin)
|
||||
cygwin=1
|
||||
CFLAGS += -DCYGWIN
|
||||
else
|
||||
cygwin=0
|
||||
endif
|
||||
|
||||
ifeq ($(linux),1)
|
||||
CFLAGS +=
|
||||
LDFLAGS +=
|
||||
endif
|
||||
|
||||
ITTI_DIR = $(COMMON_UTILS_DIR)/itti
|
||||
|
||||
ITTI_OBJS = $(ITTI_DIR)/intertask_interface.o
|
||||
ITTI_OBJS += $(ITTI_DIR)/intertask_interface_dump.o
|
||||
ITTI_OBJS += $(ITTI_DIR)/backtrace.o
|
||||
ITTI_OBJS += $(ITTI_DIR)/memory_pools.o
|
||||
ITTI_OBJS += $(ITTI_DIR)/signals.o
|
||||
ITTI_OBJS += $(ITTI_DIR)/timer.o
|
||||
|
||||
|
||||
HASHTABLE_DIR = $(COMMON_UTILS_DIR)/collection/hashtable
|
||||
MSC_DIR = $(COMMON_UTILS_DIR)/msc
|
||||
|
||||
HASHTABLE_OBJS = $(HASHTABLE_DIR)/hashtable.o
|
||||
HASHTABLE_OBJS += $(HASHTABLE_DIR)/obj_hashtable.o
|
||||
|
||||
UTILS_OBJS = $(ITTI_OBJS) $(HASHTABLE_OBJS)
|
||||
|
||||
UTILS_incl = \
|
||||
-I$(COMMON_UTILS_DIR) \
|
||||
-I$(HASHTABLE_DIR) \
|
||||
-I$(ITTI_DIR) \
|
||||
-I$(MSC_DIR)
|
||||
|
||||
print-% : ; @echo $* = $($*)
|
||||
@@ -184,8 +184,30 @@ extern T_cache_t *T_cache;
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/* we have 4 versions of T_HEADER:
|
||||
* - bad quality C++ version with time
|
||||
* - good quality C version with time
|
||||
* - bad quality C++ version without time
|
||||
* - good quality C version without time
|
||||
*/
|
||||
|
||||
#ifdef T_SEND_TIME
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/* C++ version of T_HEADER with time */
|
||||
#define T_HEADER(x) \
|
||||
do { \
|
||||
struct timespec T_HEADER_time; \
|
||||
if (clock_gettime(CLOCK_REALTIME, &T_HEADER_time)) abort(); \
|
||||
memcpy(T_LOCAL_buf, &T_HEADER_time, sizeof(struct timespec)); \
|
||||
T_LOCAL_size += sizeof(struct timespec); \
|
||||
T_PUT_int(1, (int)(uintptr_t)(x)); \
|
||||
} while (0)
|
||||
|
||||
#else /* #ifdef __cplusplus */
|
||||
|
||||
/* C version of T_HEADER with time */
|
||||
#define T_HEADER(x) \
|
||||
do { \
|
||||
if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \
|
||||
@@ -201,8 +223,21 @@ extern T_cache_t *T_cache;
|
||||
T_PUT_int(1, (int)(uintptr_t)(x)); \
|
||||
} while (0)
|
||||
|
||||
#endif /* #ifdef __cplusplus */
|
||||
|
||||
#else /* #ifdef T_SEND_TIME */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/* C++ version of T_HEADER without time */
|
||||
#define T_HEADER(x) \
|
||||
do { \
|
||||
T_PUT_int(1, (int)(uintptr_t)(x)); \
|
||||
} while (0)
|
||||
|
||||
#else /* #ifdef __cplusplus */
|
||||
|
||||
/* C version of T_HEADER without time */
|
||||
#define T_HEADER(x) \
|
||||
do { \
|
||||
if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \
|
||||
@@ -214,6 +249,8 @@ extern T_cache_t *T_cache;
|
||||
T_PUT_int(1, (int)(uintptr_t)(x)); \
|
||||
} while (0)
|
||||
|
||||
#endif /* #ifdef __cplusplus */
|
||||
|
||||
#endif /* #ifdef T_SEND_TIME */
|
||||
|
||||
#define T1(t) \
|
||||
|
||||
@@ -28,7 +28,7 @@ ID = ENB_PHY_DLSCH_UE_NACK
|
||||
ID = ENB_PHY_ULSCH_UE_DCI
|
||||
DESC = eNodeB uplink UE specific DCI as sent by the PHY layer
|
||||
GROUP = ALL:PHY:GRAPHIC:ENB
|
||||
FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid : int,mcs : int,round : int,first_rb : int,nb_rb : int,TBS
|
||||
FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid : int,mcs : int,round : int,first_rb : int,nb_rb : int,TBS : int,L : int,firstCCE
|
||||
ID = ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION
|
||||
DESC = eNodeB uplink UE retransmission due to PHICH NACK (see generate_phich_top)
|
||||
GROUP = ALL:PHY:GRAPHIC:ENB
|
||||
|
||||
@@ -65,7 +65,7 @@ _Assert_(cOND, _Assert_Exit_, #vALUE1 ": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "
|
||||
(intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3)
|
||||
|
||||
#define DevCheck4(cOND, vALUE1, vALUE2, vALUE3, vALUE4) \
|
||||
_Assert_(cOND, _Assert_Exit_, #vALUE1": %"PRIdMAX"\n"#vALUE2": %"PRIdMAX"\n"#vALUE3": %"PRIdMAX"\n"#vALUE4": %"PRIdMAX"\n\n", \
|
||||
_Assert_(cOND, _Assert_Exit_, #vALUE1": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "\n" #vALUE3 ": %" PRIdMAX "\n" #vALUE4 ": %" PRIdMAX "\n\n", \
|
||||
(intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3, (intmax_t)vALUE4)
|
||||
|
||||
#define DevParam(vALUE1, vALUE2, vALUE3) DevCheck(0, vALUE1, vALUE2, vALUE3)
|
||||
|
||||
@@ -77,7 +77,7 @@ typedef struct items_group_s {
|
||||
} items_group_t;
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static const items_group_position_t ITEMS_GROUP_POSITION_INVALID = -1;
|
||||
//static const items_group_position_t ITEMS_GROUP_POSITION_INVALID = -1;
|
||||
static const items_group_index_t ITEMS_GROUP_INDEX_INVALID = -1;
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/* This module provides a separate process to run system().
|
||||
* The communication between this process and the main processing
|
||||
* is done through unix pipes.
|
||||
*
|
||||
* Motivation: the UE sets its IP address using system() and
|
||||
* that disrupts realtime processing in some cases. Having a
|
||||
* separate process solves this problem.
|
||||
*/
|
||||
|
||||
#include "system.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_COMMAND 4096
|
||||
|
||||
static int command_pipe_read;
|
||||
static int command_pipe_write;
|
||||
static int result_pipe_read;
|
||||
static int result_pipe_write;
|
||||
|
||||
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static int module_initialized = 0;
|
||||
|
||||
/********************************************************************/
|
||||
/* util functions */
|
||||
/********************************************************************/
|
||||
|
||||
static void lock_system(void)
|
||||
{
|
||||
if (pthread_mutex_lock(&lock) != 0) {
|
||||
printf("pthread_mutex_lock fails\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void unlock_system(void)
|
||||
{
|
||||
if (pthread_mutex_unlock(&lock) != 0) {
|
||||
printf("pthread_mutex_unlock fails\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void write_pipe(int p, char *b, int size)
|
||||
{
|
||||
while (size) {
|
||||
int ret = write(p, b, size);
|
||||
if (ret <= 0) exit(0);
|
||||
b += ret;
|
||||
size -= ret;
|
||||
}
|
||||
}
|
||||
|
||||
static void read_pipe(int p, char *b, int size)
|
||||
{
|
||||
while (size) {
|
||||
int ret = read(p, b, size);
|
||||
if (ret <= 0) exit(0);
|
||||
b += ret;
|
||||
size -= ret;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/* background process */
|
||||
/********************************************************************/
|
||||
|
||||
/* This function is run by background process. It waits for a command,
|
||||
* runs it, and reports status back. It exits (in normal situations)
|
||||
* when the main process exits, because then a "read" on the pipe
|
||||
* will return 0, in which case "read_pipe" exits.
|
||||
*/
|
||||
static void background_system_process(void)
|
||||
{
|
||||
int len;
|
||||
int ret;
|
||||
char command[MAX_COMMAND+1];
|
||||
|
||||
while (1) {
|
||||
read_pipe(command_pipe_read, (char*)&len, sizeof(int));
|
||||
read_pipe(command_pipe_read, command, len);
|
||||
ret = system(command);
|
||||
write_pipe(result_pipe_write, (char *)&ret, sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/* background_system() */
|
||||
/* return -1 on error, 0 on success */
|
||||
/********************************************************************/
|
||||
|
||||
int background_system(char *command)
|
||||
{
|
||||
int res;
|
||||
int len;
|
||||
|
||||
if (module_initialized == 0) {
|
||||
printf("FATAL: calling 'background_system' but 'start_background_system' was not called\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
len = strlen(command)+1;
|
||||
if (len > MAX_COMMAND) {
|
||||
printf("FATAL: command too long. Increase MAX_COMMAND (%d).\n", MAX_COMMAND);
|
||||
printf("command was: '%s'\n", command);
|
||||
abort();
|
||||
}
|
||||
/* only one command can run at a time, so let's lock/unlock */
|
||||
lock_system();
|
||||
write_pipe(command_pipe_write, (char*)&len, sizeof(int));
|
||||
write_pipe(command_pipe_write, command, len);
|
||||
read_pipe(result_pipe_read, (char*)&res, sizeof(int));
|
||||
unlock_system();
|
||||
if (res == -1 || !WIFEXITED(res) || WEXITSTATUS(res) != 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/* start_background_system() */
|
||||
/* initializes the "background system" module */
|
||||
/* to be called very early by the main processing */
|
||||
/********************************************************************/
|
||||
|
||||
void start_background_system(void)
|
||||
{
|
||||
int p[2];
|
||||
pid_t son;
|
||||
|
||||
module_initialized = 1;
|
||||
|
||||
if (pipe(p) == -1) {
|
||||
perror("pipe");
|
||||
exit(1);
|
||||
}
|
||||
command_pipe_read = p[0];
|
||||
command_pipe_write = p[1];
|
||||
|
||||
if (pipe(p) == -1) {
|
||||
perror("pipe");
|
||||
exit(1);
|
||||
}
|
||||
result_pipe_read = p[0];
|
||||
result_pipe_write = p[1];
|
||||
|
||||
son = fork();
|
||||
if (son == -1) {
|
||||
perror("fork");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (son) {
|
||||
close(result_pipe_write);
|
||||
close(command_pipe_read);
|
||||
return;
|
||||
}
|
||||
|
||||
close(result_pipe_read);
|
||||
close(command_pipe_write);
|
||||
|
||||
background_system_process();
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef _SYSTEM_H_OAI_
|
||||
#define _SYSTEM_H_OAI_
|
||||
|
||||
/****************************************************
|
||||
* send a command to the background process
|
||||
* return -1 on error, 0 on success
|
||||
****************************************************/
|
||||
|
||||
int background_system(char *command);
|
||||
|
||||
/****************************************************
|
||||
* initialize the background process
|
||||
* to be called very early
|
||||
****************************************************/
|
||||
|
||||
void start_background_system(void);
|
||||
|
||||
#endif /* _SYSTEM_H_OAI_ */
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef _TIME_UTILS_H_
|
||||
#define _TIME_UTILS_H_
|
||||
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static inline int64_t clock_difftime_ns(struct timespec start, struct timespec end)
|
||||
{
|
||||
struct timespec temp;
|
||||
int64_t temp_ns;
|
||||
|
||||
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||
} else {
|
||||
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||
}
|
||||
temp_ns = (int64_t)(temp.tv_sec) * (int64_t)1000000000 + (temp.tv_nsec);
|
||||
return temp_ns;
|
||||
}
|
||||
|
||||
#endif /* _TIME_UTILS_H_ */
|
||||
@@ -0,0 +1,107 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "utils.h"
|
||||
|
||||
void *calloc_or_fail(size_t size) {
|
||||
void *ptr = calloc(1, size);
|
||||
if (ptr == NULL) {
|
||||
fprintf(stderr, "[UE] Failed to calloc %zu bytes", size);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *malloc_or_fail(size_t size) {
|
||||
void *ptr = malloc(size);
|
||||
if (ptr == NULL) {
|
||||
fprintf(stderr, "[UE] Failed to malloc %zu bytes", size);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
** **
|
||||
** Name: hex_char_to_hex_value() **
|
||||
** **
|
||||
** Description: Converts an hexadecimal ASCII coded digit into its value. **
|
||||
** **
|
||||
** Inputs: c: A char holding the ASCII coded value **
|
||||
** Others: None **
|
||||
** **
|
||||
** Outputs: None **
|
||||
** Return: Converted value (-1 on error) **
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
int hex_char_to_hex_value (char c)
|
||||
{
|
||||
if (!((c >= 'a' && c <= 'f') ||
|
||||
(c >= 'A' && c <= 'F') ||
|
||||
(c >= '0' && c <= '9')))
|
||||
return -1;
|
||||
|
||||
if (c >= 'A') {
|
||||
/* Remove case bit */
|
||||
c &= ~('a' ^ 'A');
|
||||
|
||||
return (c - 'A' + 10);
|
||||
} else {
|
||||
return (c - '0');
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
** **
|
||||
** Name: hex_string_to_hex_value() **
|
||||
** **
|
||||
** Description: Converts an hexadecimal ASCII coded string into its value.**
|
||||
** **
|
||||
** Inputs: hex_value: A pointer to the location to store the **
|
||||
** conversion result **
|
||||
** size: The size of hex_value in bytes **
|
||||
** Others: None **
|
||||
** **
|
||||
** Outputs: hex_value: Converted value **
|
||||
** Return: 0 on success, -1 on error **
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
int hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (strlen(hex_string) != size*2) {
|
||||
fprintf(stderr, "the string '%s' should be of length %d\n", hex_string, size*2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=0; i < size; i++) {
|
||||
int a = hex_char_to_hex_value(hex_string[2 * i]);
|
||||
int b = hex_char_to_hex_value(hex_string[2 * i + 1]);
|
||||
if (a == -1 || b == -1) goto error;
|
||||
hex_value[i] = (a << 4) | b;
|
||||
}
|
||||
return 0;
|
||||
|
||||
error:
|
||||
fprintf(stderr, "the string '%s' is not a valid hexadecimal string\n", hex_string);
|
||||
for (i=0; i < size; i++)
|
||||
hex_value[i] = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *itoa(int i) {
|
||||
char buffer[64];
|
||||
int ret;
|
||||
|
||||
ret = snprintf(buffer, sizeof(buffer), "%d",i);
|
||||
if ( ret <= 0 ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return strdup(buffer);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef _UTILS_H
|
||||
#define _UTILS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
void *calloc_or_fail(size_t size);
|
||||
void *malloc_or_fail(size_t size);
|
||||
|
||||
// Converts an hexadecimal ASCII coded digit into its value. **
|
||||
int hex_char_to_hex_value (char c);
|
||||
// Converts an hexadecimal ASCII coded string into its value.**
|
||||
int hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size);
|
||||
|
||||
char *itoa(int i);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user