mirror of
https://github.com/Ysurac/openmptcprouter.git
synced 2025-03-09 15:40:20 +00:00
158 lines
3.3 KiB
C
158 lines
3.3 KiB
C
#include <common.h>
|
|
|
|
#ifdef CONFIG_MNFINFO_SUPPORT
|
|
|
|
#include <mnf_info.h>
|
|
#include <linux/ctype.h>
|
|
|
|
#ifndef min
|
|
#define min(a, b) ((a) < (b) ? (a) : (b))
|
|
#endif
|
|
|
|
mnf_field_t *mnf_get_field_info_short(char name)
|
|
{
|
|
for (mnf_field_t *field = mnf_fields; field->short_name != '\0'; field++) {
|
|
if (name == field->short_name)
|
|
return field;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
mnf_field_t *mnf_get_field_info_long(const char *name)
|
|
{
|
|
for (mnf_field_t *field = mnf_fields; field->short_name != '\0'; field++) {
|
|
if (!strcmp(name, field->long_name))
|
|
return field;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int mnf_get_field(const char *name, void *result)
|
|
{
|
|
mnf_field_t *field = mnf_get_field_info_long(name);
|
|
|
|
if (!field)
|
|
return -1;
|
|
|
|
return mnf_flash_read(field, result);
|
|
}
|
|
|
|
int mnf_set_field(const char *name, const void *value)
|
|
{
|
|
mnf_field_t *field = mnf_get_field_info_long(name);
|
|
int err;
|
|
|
|
if (!field)
|
|
return -1;
|
|
|
|
err = mnf_flash_write_init();
|
|
if (err)
|
|
return err;
|
|
|
|
err = mnf_flash_write(field, value);
|
|
if (err)
|
|
return err; // If write fails, we should cancel the transaction and not call finalize()
|
|
|
|
return mnf_flash_write_finalize();
|
|
}
|
|
|
|
static void apply_mnf_order(mnf_field_t *field, char *buf)
|
|
{
|
|
if (field->flags & MNF_FIELD_REVERSED) {
|
|
for (int i = 0; i < (field->length) / 2; i++) {
|
|
char tmp = buf[i];
|
|
buf[i] = buf[field->length - 1 - i];
|
|
buf[field->length - 1 - i] = tmp;
|
|
}
|
|
}
|
|
}
|
|
|
|
static char int_to_hexchar(unsigned val)
|
|
{
|
|
const char *hex_chars = "0123456789ABCDEF";
|
|
|
|
if (val >= 16)
|
|
return '\0';
|
|
|
|
return hex_chars[val];
|
|
}
|
|
|
|
static void bin_to_hexstr(const char *input, char *result, int len)
|
|
{
|
|
int i;
|
|
for (i = 0; i < len; i++) {
|
|
int high_nibble = (input[i] >> 4) & 0xf;
|
|
int low_nibble = input[i] & 0xf;
|
|
|
|
result[i * 2] = int_to_hexchar(high_nibble);
|
|
result[(i * 2) + 1] = int_to_hexchar(low_nibble);
|
|
}
|
|
|
|
result[i * 2] = '\0';
|
|
}
|
|
|
|
void mnf_field_to_str(mnf_field_t *field, char *input, char *result)
|
|
{
|
|
apply_mnf_order(field, input);
|
|
|
|
if (field->flags & MNF_FIELD_BINARY) { // format the result as hex
|
|
bin_to_hexstr(input, result, field->length);
|
|
} else { // truncate the string to the first non-ascii char or field len, whichever comes first
|
|
int i;
|
|
for (i = 0; i < field->length; i++) {
|
|
if (input[i] & 0x80)
|
|
break;
|
|
}
|
|
memcpy(result, input, i);
|
|
result[i] = 0x00;
|
|
}
|
|
}
|
|
|
|
static int hexchar_to_int(char c)
|
|
{
|
|
const char *hex_chars = "0123456789ABCDEF";
|
|
char *found = strchr(hex_chars, toupper(c));
|
|
|
|
if (!found)
|
|
return -1;
|
|
|
|
return found - hex_chars;
|
|
}
|
|
|
|
static int hexstr_to_bin(const char *input, char *result, int len)
|
|
{
|
|
for (int i = 0; i < len; i++) {
|
|
char high_char = input[i * 2];
|
|
char low_char = input[(i * 2) + 1];
|
|
|
|
if (high_char == 0x00)
|
|
break;
|
|
|
|
int high_nibble = hexchar_to_int(high_char);
|
|
int low_nibble = hexchar_to_int(low_char);
|
|
|
|
if (low_nibble < 0 || high_nibble < 0)
|
|
return 1;
|
|
|
|
result[i] = ((unsigned char)high_nibble << 4) | (unsigned char)low_nibble;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int mnf_str_to_field(mnf_field_t *field, const char *input, char *result)
|
|
{
|
|
memset(result, 0xff, field->length);
|
|
|
|
if (field->flags & MNF_FIELD_BINARY) { // parse the input as hex encoded string
|
|
if (hexstr_to_bin(input, result, field->length))
|
|
return 1;
|
|
} else { // copy the string directly, ommiting trailing null byte.
|
|
memcpy(result, input, min(strlen(input), field->length));
|
|
}
|
|
|
|
apply_mnf_order(field, result);
|
|
return 0;
|
|
}
|
|
|
|
#endif
|