static uint8_t _text_parser(char *str, cmdObj_t *cmd) { char *ptr_rd, *ptr_wr; // read and write pointers char separators[] = {" =:|\t"}; // any separator someone might use // string pre-processing cmd_reset_obj(cmd); // initialize config object if (*str == '$') str++; // ignore leading $ for (ptr_rd = ptr_wr = str; *ptr_rd!=NUL; ptr_rd++, ptr_wr++) { *ptr_wr = tolower(*ptr_rd); // convert string to lower case if (*ptr_rd==',') { *ptr_wr = *(++ptr_rd); // skip over comma } } *ptr_wr = NUL; // field processing cmd->type = TYPE_NULL; if ((ptr_rd = strpbrk(str, separators)) == NULL) { // no value part strncpy(cmd->token, str, CMD_TOKEN_LEN); } else { *ptr_rd = NUL; // terminate at end of name strncpy(cmd->token, str, CMD_TOKEN_LEN); str = ++ptr_rd; cmd->value = strtod(str, &ptr_rd); // ptr_rd used as end pointer if (ptr_rd != str) { cmd->type = TYPE_FLOAT; } } if ((cmd->index = cmd_get_index("",cmd->token)) == NO_MATCH) { return (SC_UNRECOGNIZED_COMMAND); } return (SC_OK); }
/* * rpt_init_status_report() * * Call this function to completely re-initialze the status report * Sets SR list to hard-coded defaults and re-initializes sr values in NVM */ void rpt_init_status_report() { cmdObj_t *cmd = cmd_reset_list(); // used for status report persistence locations char sr_defaults[CMD_STATUS_REPORT_LEN][CMD_TOKEN_LEN+1] = { SR_DEFAULTS }; // see settings.h cm.status_report_counter = (cfg.status_report_interval / RTC_MILLISECONDS); // RTC fires every 10 ms cmd->index = cmd_get_index("","se00"); // set first SR persistence index for (uint8_t i=0; i < CMD_STATUS_REPORT_LEN ; i++) { if (sr_defaults[i][0] == NUL) break; // quit on first blank array entry cfg.status_report_value[i] = -1234567; // pre-load values with an unlikely number cmd->value = cmd_get_index("", sr_defaults[i]); // load the index for the SR element cmd_set(cmd); cmd_persist(cmd); // conditionally persist - automatic by cmd_persis() cmd->index++; // increment SR NVM index } }
void rpt_populate_unfiltered_status_report() { char tmp[CMD_TOKEN_LEN+1]; cmdObj_t *cmd = cmd_reset_list(); // sets *cmd to the start of the body cmd->objtype = TYPE_PARENT; // setup the parent object strcpy(cmd->token, "sr"); // sprintf_P(cmd->token, PSTR("sr")); // alternate form of above: less RAM, more FLASH & cycles cmd->index = cmd_get_index("","sr"); // set the index - may be needed by calling function cmd = cmd->nx; // no need to check for NULL as list has just been reset for (uint8_t i=0; i<CMD_STATUS_REPORT_LEN; i++) { if ((cmd->index = cfg.status_report_list[i]) == 0) { break;} cmd_get_cmdObj(cmd); strcpy(tmp, cmd->group); // concatenate groups and tokens strcat(tmp, cmd->token); strcpy(cmd->token, tmp); if ((cmd = cmd->nx) == NULL) return; // should never be NULL unless SR length exceeds available buffer array } }
stat_t _json_parser_kernal(char *str) { uint8_t status; int8_t depth; cmdObj_t *cmd = cmd_reset_list(); // get a fresh cmdObj list char group[CMD_GROUP_LEN+1] = {""}; // group identifier - starts as NUL int8_t i = CMD_BODY_LEN; ritorno(_normalize_json_string(str, JSON_OUTPUT_STRING_MAX)); // return if error // parse the JSON command into the cmd body do { if (--i == 0) { return (STAT_JSON_TOO_MANY_PAIRS); } // length error if ((status = _get_nv_pair_strict(cmd, &str, &depth)) > STAT_EAGAIN) { // erred out return (status); } // propagate the group from previous NV pair (if relevant) if (group[0] != NUL) { strncpy(cmd->group, group, CMD_GROUP_LEN);// copy the parent's group to this child } // validate the token and get the index if ((cmd->index = cmd_get_index(cmd->group, cmd->token)) == NO_MATCH) { return (STAT_UNRECOGNIZED_COMMAND); } if ((cmd_index_is_group(cmd->index)) && (cmd_group_is_prefixed(cmd->token))) { strncpy(group, cmd->token, CMD_GROUP_LEN);// record the group ID } if ((cmd = cmd->nx) == NULL) return (STAT_JSON_TOO_MANY_PAIRS);// Not supposed to encounter a NULL } while (status != STAT_OK); // breaks when parsing is complete // execute the command cmd = cmd_body; if (cmd->objtype == TYPE_NULL){ // means GET the value ritorno(cmd_get(cmd)); // ritorno returns w/status on any errors } else { ritorno(cmd_set(cmd)); // set value or call a function (e.g. gcode) cmd_persist(cmd); } return (STAT_OK); // only successful commands exit through this point }
/* * rpt_set_status_report() - interpret an sr setup string and return current report */ stat_t rpt_set_status_report(cmdObj_t *cmd) { uint8_t elements = 0; index_t status_report_list[CMD_STATUS_REPORT_LEN]; memset(status_report_list, 0, sizeof(status_report_list)); index_t sr_start = cmd_get_index("","se00"); // set first SR persistence index for (uint8_t i=0; i<CMD_STATUS_REPORT_LEN; i++) { if (((cmd = cmd->nx) == NULL) || (cmd->objtype == TYPE_EMPTY)) { break;} if ((cmd->objtype == TYPE_BOOL) && (cmd->value == true)) { status_report_list[i] = cmd->index; cmd->value = cmd->index; // persist the index as the value cmd->index = sr_start + i; // index of the SR persistence location cmd_persist(cmd); elements++; } else { return (STAT_INPUT_VALUE_UNSUPPORTED); } } if (elements == 0) { return (STAT_INPUT_VALUE_UNSUPPORTED);} memcpy(cfg.status_report_list, status_report_list, sizeof(status_report_list)); rpt_populate_unfiltered_status_report(); // return current values return (STAT_OK); }