/** \file lib_Utils.c
* \brief Este fichero contiene un compendio de funciones de utilidad varia.
*
* \author Diego Márquez García-Cuervo \n <diego@indalosecurity.com> \n <micropic@garcia-cuervo.com>
*/
/** \brief Función auxiliar que convierte de \c BIN a \c BCD
*
* \param binary_value Valor binario a convertir.
* \return Valor BCD convertido.
*/
int8 bin_to_bcd(int8 binary_value){
int8 temp;
int8 retval;
temp = binary_value;
retval = 0;
while(1){
if(temp >= 10){
temp -= 10;
retval += 0x10;
}else{
retval += temp;
break;
}
}
return(retval);
}
/** \brief Función auxiliar que convierte de \c BCD a \c BIN
*
* \param bcd_value Valor BCD a convertir.
* \return Valor Binario convertido.
*/
int8 bcd_to_bin(int8 bcd_value){
int8 temp;
temp = bcd_value;
temp >>= 1;
temp &= 0x78;
return(temp + (temp >> 2) + (bcd_value & 0x0f));
}
/** \brief Función que obtiene el nombre del día de la semana.
*
* Convierte el orden del día de la semana a su correspondiente nombre Lunes=1, Martes=2 ... Domingo=7.
*
* \param dow Orden del Día de la semana.
* \param[out] *pF Puntero a string donde cargar el nombre del día de la semana.
* \return void
*/
void get_name_day_of_week(int8 dow, char *pF){
strcpy(pF,"\0");
switch(dow){
case 1: strcpy(pF,"Lunes"); break;
case 2: strcpy(pF,"Martes"); break;
case 3: strcpy(pF,"Miércoles"); break;
case 4: strcpy(pF,"Jueves"); break;
case 5: strcpy(pF,"Viernes"); break;
case 6: strcpy(pF,"Sábado"); break;
case 7: strcpy(pF,"Domingo"); break;
}
}
/** \brief Función que convierte un Byte (de 8 bits) a bits string ASCII.
*
* Convierte un Byte (de 8 bits) a string ASCII terminado en NULL (\\0).
*
* \param val Valor del Byte a convertir.
* \param[out] pF Puntero a string_null_ended.
*
* \return void
*/
void int8_to_bits_string(int8 val,char* pF){
int8 i,j;
for(i=0,j=7;i<8;i++,j--){
pF[i]=bit_test(val,j)+'0';
}
pF[8]='\0';
}
/** \brief Función que convierte un bits string ASCII a un Byte (de 8 bits).
*
* Convierte un string ASCII terminado en NULL (\\0) a Byte (de 8 bits).
*
* \param pF Puntero a string_null_ended.
*
* \return int8 Valor convertido.
*/
int8 bits_string_to_int8(char* pF){
int8 i,j,ret=0;
for(i=0,j=7;i<8;i++,j--){
if(pF[i]=='1'){
bit_set(ret,j);
}
}
return ret;
}
/** \brief Función que rellena con un caracter dado un string a partir de NULL hasta una longitud dada.
*
* \param c Carácter de relleno.
* \param maxlen Longitud máxima del string.
* \param[out] pF Puntero a string_null_ended a rellenar.
*
* \return void
*/
void fill_end_with_char(char c, int8 maxlen,char* pF){
int8 i;
int1 start=0;
for(i=0;i<maxlen;i++){
if(start==0){
if(pF[i]=='\0'){
start=1;
}
}
if(start==1){
pf[i]=c;
}
}
pF[maxlen]='\0';
}
/** \brief Función que convierte un string numérico decimal ASCII NULL-END a su valor entero (8 bits).
*
* \param pF Puntero al buffer que contiene el string numérico ASCII.
*
* \return int8 Valor numérico.
*/
int8 str_to_int8(char* pF){
int8 ret=0,i,l,m=1;
l=strlen(pF)-1;
for(i=l;i<255;i--){
if(isdigit(pF[i])){
ret+= m * (pF[i]-'0');
m = m * 10;
} else break;
}
//printf("StrToInt %s (%u)\r\n",pF,ret);
return ret;
}
/** \brief Función decodifica una variable TimeStamp extrayendo sus componentes.
*
* Acepta una variable TimeStamp y devuelve valores enteros de Año, Mes, Día, Hora, Minuto, y Segundo.
* \param pF Puntero a string TimeStamp
* \param[out] day Dia
* \param[out] mth Mes
* \param[out] year Año (4 dígitos, int16)
* \param[out] hr Hora
* \param[out] min Minuto
* \param[out] sec Segundo
* \see encode_timestamp()
*/
void decode_timestamp(char *pF, int8 &day, int8 &mth, int16 &year, int8 &hr, int8 &min, int8 &sec){
char sval[]="00";
sval[2]='\0';
sval[0]=pF[2]; sval[1]=pF[3]; year= 2000+str_to_int8(sval);
sval[0]=pF[5]; sval[1]=pF[6]; mth = str_to_int8(sval);
sval[0]=pF[8]; sval[1]=pF[9]; day = str_to_int8(sval);
sval[0]=pF[11]; sval[1]=pF[12]; hr = str_to_int8(sval);
sval[0]=pF[14]; sval[1]=pF[15]; min = str_to_int8(sval);
sval[0]=pF[17]; sval[1]=pF[18]; sec = str_to_int8(sval);
}
/** \brief Función codifica una variable TimeStamp dando sus componentes.
*
* Acepta variables de valores enteros de Año, Mes, Día, Hora, Minuto, y Segundo y devuelve puntero a variable de tipo Timestamp.
* \param[out] pF Puntero a string TimeStamp
* \param day Dia
* \param mth Mes
* \param year Año (4 dígitos, int16)
* \param hr Hora
* \param min Minuto
* \param sec Segundo
* \see encode_timestamp()
*/
void encode_timestamp(char *pF, int8 day, int8 mth, int16 year, int8 hr, int8 min, int8 sec){
sprintf(pF,"%Lu-%2u-%2u_%2u:%2u:%2u\0",year,mth,day,hr,min,sec);
replace_char(' ','0',pF);
replace_char('_',' ',pF);
}
/** \brief Función que devuelve la mayor fecha posible en formato Timestamp.
*
* \param[out] pF Puntero a string TimeStamp
*/
void give_me_greater_timestamp(char *pF){
strcpy(pF,greater_Timestamp);
}
/** \brief Función que convierte una variable TimeStamp en una tDateTimeShort.
*
* Acepta una variable TimeStamp y devuelve los valores correspondientes de la estructura tDateTimeShort (int8) de Año, Mes, Día, Hora y Minuto.
* \param pF Puntero a string TimeStamp
* \param[out] pDTS Puntero a una variable tDateTimeShort
*/
void timestamp_to_DateTimeShort(char *pF, struct tDateTimeShort * pDTS){
char sval[]="00";
// Info Debug
//printf("\r\ntimestamp_to_DateTimeShort recibe: %s",pf);
sval[2]='\0';
sval[0]=pF[2]; sval[1]=pF[3]; pDTS->year= str_to_int8(sval);
sval[0]=pF[5]; sval[1]=pF[6]; pDTS->mth = str_to_int8(sval);
sval[0]=pF[8]; sval[1]=pF[9]; pDTS->day = str_to_int8(sval);
sval[0]=pF[11]; sval[1]=pF[12]; pDTS->hr = str_to_int8(sval);
sval[0]=pF[14]; sval[1]=pF[15]; pDTS->min = str_to_int8(sval);
// Info Debug
//printf("\r\ntimestamp_to_DateTimeShort devuelve: %u %u %u %u %u\r\n",pDTS->year,pDTS->mth,pDTS->day,pDTS->hr,pDTS->min);
}
/** \brief Reemplaza carácter en string null-terminated.
*
* \param c Carácter a sustituir.
* \param p Carácter nuevo a insertar.
* \param[out] pF Puntero a string null-terminated.
*
* \return void
*/
void replace_char(char c, char p, char* pF){
int8 i;
char x;
x=pF[0];
for(i=0;i<max_len_buffer,x!='\0';i++){
x=pf[i];
if(x==c){
pF[i]=p;
}
}
}
/** \brief Inicializa un Buffer
*
* Esta función inicializa a "\0" todos los bytes de un Buffer.\n
*
* \return void
*/
void init_buffer(int16 maxlen, char *buffer){
int16 i;
for(i=0;i<maxlen;i++){
buffer[i]='\0';
}
}
/** \brief Función que convierte un carácter Hexadecimal ASCII NULL-END a su valor entero de 8 bits.
*
* \param d Caracter Hexadecimal a convertir.
*
* \return int8 Valor numérico.
*/
int8 ascii_to_hex(char d){
int r=0x00;
if(isxdigit(d)){
if(isdigit(d)){
r=d-'0';
}
if(isalpha(d)){
d=toupper(d);
r=10+(d-'A');
}
}
return(r);
}
/** \brief Función que convierte un string numérico Hexadecimal ASCII NULL-END a su valor entero de 8 bits.
*
* \param pF Puntero al buffer que contiene el string numérico ASCII Hexadecimal de 2 digitos (00h a FFh).
*
* \return int8 Valor numérico.
*/
int8 hex_to_int8(char* pF){
int8 i,ret;
ret=0;
for(i=1;i!=255;i--){
ret+=ascii_to_hex(pF[i])*((15*(1-i))+1);
}
//printf("hex_to_int8 recibe: %s valor: %X (%u)\r\n",pF,ret,ret);
return ret;
}
/** \brief Función que convierte un string numérico Hexadecimal ASCII NULL-END a su valor entero de 16 bits.
*
* \param pF Puntero al buffer que contiene el string numérico ASCII Hexadecimal de 4 digitos (0000h a FFFFh).
*
* \return int16 Valor numérico.
*/
int16 hex_to_int16(char* pF){
int8 i, p2, p1;
int16 ret;
p1=hex_to_int8(&pF[2]);
p2=hex_to_int8(&pF[0]);
ret=make16(p2,p1);
//printf("hex_to_int16 recibe: %s p2: %LX p1 %LX valor: %LX (%Lu)\r\n",pF,p2,p1,ret,ret);
return ret;
}
/** \brief Función que convierte un string numérico Hexadecimal ASCII NULL-END a su valor entero de 32 bits.
*
* \param pF Puntero al buffer que contiene el string numérico ASCII.
*
* \return int32 Valor numérico.
*/
int32 hex_to_int32(char* pF){
int32 ret;
int16 p1,p2;
p1=hex_to_int16(&pF[4]);
p2=hex_to_int16(&pF[0]);
ret = make32(p2, p1);
//printf("hex_to_int32 recibe: %s p2: %LX p1 %LX valor: %LX (%Lu)\r\n",pF,p2,p1,ret,ret);
return ret;
}
/** \brief Función que comprueba si todos los caracteres del string son iguales a uno dado.
*
* \param pF Puntero al string a investigar.
* \param Eq Caracter a comprobar.
*
* \return int1 0 si al menos un caracter es distinto del dado, 1 si todos los caracteres son iguales al dado.
*/
int1 are_all_chars_equal_ASCII(char *pF, char Eq){
int8 ret;
int8 i,l;
ret=1;
l=strLen(pF);
for(i=0;i<l;i++){
if(pf[i]!=Eq){
ret=0;
}
}
return ret;
}
/** \brief Función que comprueba si todos los caracteres del string son '0' (ASCII Cero).
*
* \param pF Puntero al string a investigar.
*
* \return int1 0 si al menos un caracter es distinto de cero, 1 si todos los caracteres son cero.
*/
int1 are_all_chars_equal_ASCII_zero(char *pF){
int8 ret;
ret = are_all_chars_equal_ASCII(pF,'0');
return ret;
}
/** \brief Función que crea un int32 con el contenido de un tDateTimeShort (Se desprecian el componente struct .min)
*
* \param t Fecha a convertir.
*
* \return int32 valor truncado y convertido.
*/
int32 tDateTimeShort_to_int32(struct tDateTimeShort t){
int32 ret=0;
t.hr = (t.hr * 60) + t.min;
ret=make32(t.year,t.mth,t.day,t.hr);
return ret;
}
/** \brief Función que descarta los espacios en blanco por la derecha de una cadena.
*
* \param[out] pF Puntero a string_null_ended a procesar.
*
* \return void
*/
void right_trim(char* pF){
int8 i,L;
for(i=0;i<len_string;i++){
if(pF[i]=='\0'){
L=i-1;
break;
}
}
for(i=L;i>0;i--){
if(pF[i]==' '){
pF[i]='\0';
}
else{
break;
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// End of lib_utils
//
///////////////////////////////////////////////////////////////////////////////////////////////////