// (config <id> <value> <persist> Item *config(List *expression) { Item *value_item = third(expression); if (value_item) { uint8_t item = eval_as_uint8(second(expression)); uint8_t value = eval_as_uint8(value_item); uint8_t permanent = eval_as_uint8(fourth(expression)); if (item < NUM_BOOLCONFIG) { // bool set_bool_value(&bit_config, item, value); if (permanent) { uint8_t stored_config = eeprom_read_byte(CONFIG_START_ADDR); set_bool_value(&stored_config, item, value); eeprom_update_byte(CONFIG_START_ADDR, stored_config); } } else { item -= NUM_BOOLCONFIG; if (item < NUM_BYTECONFIG) { // byte byte_config[item] = value; if (permanent) { eeprom_update_byte(BYTE_CONFIG_START_ADDR, value); } } } } return 0; }
void set_bool_config(uint8_t offset, bool value, bool permanent) { set_bool_value(&bit_config, offset, value); if (permanent) { uint8_t stored_config = eeprom_read_byte(CONFIG_START_ADDR); set_bool_value(&stored_config, offset, value); eeprom_update_byte(CONFIG_START_ADDR, stored_config); } }
static int parse_logical_AND_expr(int need_eval, cfg_cond_value_t *prv) { cfg_cond_value_t v1, v2; int b = 0, r; if ((r = parse_OR_expr(need_eval, &v1)) < 0) return -1; if (need_eval) { while (parsecfg_state.raw.s[parsecfg_state.raw_i] > 0 && parsecfg_state.raw.s[parsecfg_state.raw_i] <= ' ') parsecfg_state.raw_i++; if (parsecfg_state.raw.s[parsecfg_state.raw_i] != '&' || parsecfg_state.raw.s[parsecfg_state.raw_i + 1] != '&') { *prv = v1; return r; } if (!convert_to_bool(&v1)) { set_bool_value(prv, 0); b = 0; need_eval = 0; free_value(&v1); } } while (1) { while (parsecfg_state.raw.s[parsecfg_state.raw_i] > 0 && parsecfg_state.raw.s[parsecfg_state.raw_i] <= ' ') parsecfg_state.raw_i++; if (parsecfg_state.raw.s[parsecfg_state.raw_i] != '&' || parsecfg_state.raw.s[parsecfg_state.raw_i + 1] != '&') break; parsecfg_state.raw_i += 2; while (parsecfg_state.raw.s[parsecfg_state.raw_i] > 0 && parsecfg_state.raw.s[parsecfg_state.raw_i] <= ' ') parsecfg_state.raw_i++; if (parse_OR_expr(need_eval, &v2) < 0) return -1; if (need_eval && !convert_to_bool(&v2)) { set_bool_value(prv, 0); b = 0; need_eval = 0; free_value(&v2); } } if (need_eval) { set_bool_value(prv, 1); b = 1; } return b; }
void handle_firmware_configuration_request(const char *name, const char* value) { ConfigurationTree tree; if (*name == '\0') { send_app_error_response(PARAM_APP_ERROR_TYPE_BAD_PARAMETER_FORMAT, 0); return; } ConfigurationTreeNode *node = tree.FindNode(name); if (node == 0) { // TODO: improve on this error message send_app_error_response(PARAM_APP_ERROR_TYPE_BAD_PARAMETER_VALUE, PMSG(ERR_MSG_CONFIG_NODE_NOT_FOUND), name); return; } if (!node->IsLeafNode()) { // TODO: improve on this error message send_app_error_response(PARAM_APP_ERROR_TYPE_BAD_PARAMETER_VALUE, PMSG(ERR_MSG_CONFIG_NODE_NOT_COMPLETE), name); return; } if (value == 0) { if ((node->GetLeafOperations() & FIRMWARE_CONFIG_OPS_READABLE) == 0) { send_app_error_response(PARAM_APP_ERROR_TYPE_BAD_PARAMETER_VALUE, PMSG(ERR_MSG_CONFIG_NODE_NOT_READABLE)); return; } generate_value(node->GetNodeType(), tree.GetParentNode(node)->GetInstanceId(), node->GetInstanceId()); } else { if ((node->GetLeafOperations() & FIRMWARE_CONFIG_OPS_WRITEABLE) == 0) { send_app_error_response(PARAM_APP_ERROR_TYPE_BAD_PARAMETER_VALUE, PMSG(ERR_MSG_CONFIG_NODE_NOT_WRITEABLE)); return; } generate_response_start(RSP_APPLICATION_ERROR, 1); // ensure value has correct format and then attempt to set switch (node->GetLeafSetDataType()) { case LEAF_SET_DATATYPE_PIN: { long number; if (!read_pin(number, value) || number < 0 || number > UINT8_MAX) { send_app_error_response(PARAM_APP_ERROR_TYPE_BAD_PARAMETER_FORMAT, PMSG(ERR_MSG_INVALID_PIN_NUMBER), number); return; } if (!set_uint8_value(node->GetNodeType(), tree.GetParentNode(node)->GetInstanceId(), node->GetInstanceId(), number)) { return; // assume that set function has generated an error response } break; } case LEAF_SET_DATATYPE_UINT8: { long number; if (!read_number(number, value) || number < 0 || number > UINT8_MAX) { send_app_error_response(PARAM_APP_ERROR_TYPE_BAD_PARAMETER_FORMAT, PMSG(ERR_MSG_EXPECTED_UINT8_VALUE)); return; } if (!set_uint8_value(node->GetNodeType(), tree.GetParentNode(node)->GetInstanceId(), node->GetInstanceId(), number)) { return; // assume that set function has generated an error response } break; } case LEAF_SET_DATATYPE_INT16: { long number; if (!read_number(number, value)) { send_app_error_response(PARAM_APP_ERROR_TYPE_BAD_PARAMETER_FORMAT, PMSG(ERR_MSG_EXPECTED_INT16_VALUE)); return; } if (!set_int16_value(node->GetNodeType(), tree.GetParentNode(node)->GetInstanceId(), node->GetInstanceId(), number)) { return; // assume that set function has generated an error response } break; } case LEAF_SET_DATATYPE_BOOL: { bool val; if (strcmp(value, "true") == 0 || strcmp(value, "1") == 0) { val = true; } else if (strcmp(value, "false") == 0 || strcmp(value, "0") == 0) { val = false; } else { send_app_error_response(PARAM_APP_ERROR_TYPE_BAD_PARAMETER_FORMAT, PMSG(ERR_MSG_EXPECTED_BOOL_VALUE)); return; } if (!set_bool_value(node->GetNodeType(), tree.GetParentNode(node)->GetInstanceId(), node->GetInstanceId(), val)) { return; // assume that set function has generated an error response } break; } case LEAF_SET_DATATYPE_STRING: { if (!set_string_value(node->GetNodeType(), tree.GetParentNode(node)->GetInstanceId(), node->GetInstanceId(), value)) { return; // assume that set function has generated an error response } break; } case LEAF_SET_DATATYPE_FLOAT: { char *end; float val = strtod(value, &end); if (end == value || *end != '\0') { send_app_error_response(PARAM_APP_ERROR_TYPE_BAD_PARAMETER_FORMAT, PMSG(ERR_MSG_EXPECTED_FLOAT_VALUE)); return; } if (!set_float_value(node->GetNodeType(), tree.GetParentNode(node)->GetInstanceId(), node->GetInstanceId(), val)) { return; // assume that set function has generated an error response } break; } default: send_app_error_response(PARAM_APP_ERROR_TYPE_BAD_PARAMETER_FORMAT, PMSG(MSG_ERR_CANNOT_HANDLE_FIRMWARE_CONFIG_REQUEST), __LINE__); return; } send_OK_response(); } }