in IndustrialDeviceController/Software/HighLevelApp/drivers/modbus/modbus.c [654:748]
static err_code parse_point_definition(const char *ptr, int16_t len, data_point_t *p)
{
if (!ptr || len <= 0 || !p) {
return DEVICE_E_CONFIG;
}
char buf[MAX_FIELD_LENGTH + 1];
modbus_point_t *mp = &(p->d.modbus);
// set default value
mp->value_offset = 0;
mp->scale = 1;
mp->bit_offset = 0;
int16_t field_num = 0;
for (int16_t b = 0, e = 0; b < len; b = e + 1, e = b) {
while (e < len && ptr[e] != ':') {
e++;
}
if (e - b > MAX_FIELD_LENGTH) {
return DEVICE_E_CONFIG;
}
switch (field_num) {
case MODBUS_SCHEMA_FIELD_KEY:
strncpy_s(p->key, e - b + 1, ptr + b, e - b);
break;
case MODBUS_SCHEMA_FIELD_NUMBER: {
strncpy_s(buf, sizeof(buf), ptr + b, e - b);
errno = 0;
uint32_t number = strtol(buf, NULL, 10);
mp->reg_type = number / 100000;
mp->addr = number % 100000 - 1; // number start from 1, but address is from 0
if (errno || (mp->reg_type != 0 && mp->reg_type != 1 && mp->reg_type != 3 && mp->reg_type != 4)) {
return DEVICE_E_CONFIG;
};
break;
}
case MODBUS_SCHEMA_FIELD_TYPE: {
strncpy_s(buf, sizeof(buf), ptr + b, e - b);
errno = 0;
mp->data_type = strtol(buf, NULL, 10);
if (errno || mp->data_type == TYPE_INVALID || mp->data_type > TYPE_INT64_LE) {
return DEVICE_E_CONFIG;
}
break;
}
case MODBUS_SCHEMA_FIELD_BIT: {
strncpy_s(buf, sizeof(buf), ptr + b, e - b);
errno = 0;
mp->bit_offset = strtol(buf, NULL, 10);
if (errno || mp->bit_offset > 15) {
return DEVICE_E_CONFIG;
}
break;
}
case MODBUS_SCHEMA_FIELD_MULTIPLIER: {
strncpy_s(buf, sizeof(buf), ptr + b, e - b);
errno = 0;
double multiplier = strtod(buf, NULL);
if (errno || multiplier == 0) {
return DEVICE_E_CONFIG;
}
mp->scale = 1 / multiplier;
break;
}
case MODBUS_SCHEMA_FIELD_OFFSET: {
strncpy_s(buf, sizeof(buf), ptr + b, e - b);
errno = 0;
mp->value_offset = strtol(buf, NULL, 10);
if (errno) {
return DEVICE_E_CONFIG;
}
break;
}
}
field_num++;
}
// minimum is key, number, type
if (field_num < 3) {
return DEVICE_E_CONFIG;;
} else {
return DEVICE_OK;
}
}