NullMixer * NullMixer::from_text(const char *buf, unsigned &buflen) { NullMixer *nm = nullptr; /* enforce that the mixer ends with a new line */ if (!string_well_formed(buf, buflen)) { return nullptr; } if ((buflen >= 2) && (buf[0] == 'Z') && (buf[1] == ':')) { nm = new NullMixer; buflen -= 2; } return nm; }
MultirotorMixer * MultirotorMixer::from_text(Mixer::ControlCallback control_cb, uintptr_t cb_handle, const char *buf, unsigned &buflen) { MultirotorGeometry geometry; char geomname[8]; int s[4]; int used; /* enforce that the mixer ends with a new line */ if (!string_well_formed(buf, buflen)) { return nullptr; } if (sscanf(buf, "R: %7s %d %d %d %d%n", geomname, &s[0], &s[1], &s[2], &s[3], &used) != 5) { debug("multirotor parse failed on '%s'", buf); return nullptr; } if (used > (int)buflen) { debug("OVERFLOW: multirotor spec used %d of %u", used, buflen); return nullptr; } buf = skipline(buf, buflen); if (buf == nullptr) { debug("no line ending, line is incomplete"); return nullptr; } debug("remaining in buf: %d, first char: %c", buflen, buf[0]); if (!strcmp(geomname, "4+")) { geometry = MultirotorGeometry::QUAD_PLUS; } else if (!strcmp(geomname, "4x")) { geometry = MultirotorGeometry::QUAD_X; } else if (!strcmp(geomname, "4h")) { geometry = MultirotorGeometry::QUAD_H; } else if (!strcmp(geomname, "4v")) { geometry = MultirotorGeometry::QUAD_V; } else if (!strcmp(geomname, "4w")) { geometry = MultirotorGeometry::QUAD_WIDE; } else if (!strcmp(geomname, "4s")) { geometry = MultirotorGeometry::QUAD_S250AQ; } else if (!strcmp(geomname, "4dc")) { geometry = MultirotorGeometry::QUAD_DEADCAT; } else if (!strcmp(geomname, "6+")) { geometry = MultirotorGeometry::HEX_PLUS; } else if (!strcmp(geomname, "6x")) { geometry = MultirotorGeometry::HEX_X; } else if (!strcmp(geomname, "6c")) { geometry = MultirotorGeometry::HEX_COX; } else if (!strcmp(geomname, "6t")) { geometry = MultirotorGeometry::HEX_T; } else if (!strcmp(geomname, "8+")) { geometry = MultirotorGeometry::OCTA_PLUS; } else if (!strcmp(geomname, "8x")) { geometry = MultirotorGeometry::OCTA_X; } else if (!strcmp(geomname, "8c")) { geometry = MultirotorGeometry::OCTA_COX; } else if (!strcmp(geomname, "6m")) { geometry = MultirotorGeometry::DODECA_TOP_COX; } else if (!strcmp(geomname, "6a")) { geometry = MultirotorGeometry::DODECA_BOTTOM_COX; } else if (!strcmp(geomname, "2-")) { geometry = MultirotorGeometry::TWIN_ENGINE; } else if (!strcmp(geomname, "3y")) { geometry = MultirotorGeometry::TRI_Y; } else { debug("unrecognised geometry '%s'", geomname); return nullptr; } debug("adding multirotor mixer '%s'", geomname); return new MultirotorMixer( control_cb, cb_handle, geometry, s[0] / 10000.0f, s[1] / 10000.0f, s[2] / 10000.0f, s[3] / 10000.0f); }
SimpleMixer * SimpleMixer::from_text(Mixer::ControlCallback control_cb, uintptr_t cb_handle, const char *buf, unsigned &buflen) { SimpleMixer *sm = nullptr; mixer_simple_s *mixinfo = nullptr; unsigned inputs; int used; const char *end = buf + buflen; /* enforce that the mixer ends with a new line */ if (!string_well_formed(buf, buflen)) { return nullptr; } /* get the base info for the mixer */ if (sscanf(buf, "M: %u%n", &inputs, &used) != 1) { debug("simple parse failed on '%s'", buf); goto out; } buf = skipline(buf, buflen); if (buf == nullptr) { debug("no line ending, line is incomplete"); goto out; } mixinfo = (mixer_simple_s *)malloc(MIXER_SIMPLE_SIZE(inputs)); if (mixinfo == nullptr) { debug("could not allocate memory for mixer info"); goto out; } mixinfo->control_count = inputs; if (parse_output_scaler(end - buflen, buflen, mixinfo->output_scaler)) { debug("simple mixer parser failed parsing out scaler tag, ret: '%s'", buf); goto out; } for (unsigned i = 0; i < inputs; i++) { if (parse_control_scaler(end - buflen, buflen, mixinfo->controls[i].scaler, mixinfo->controls[i].control_group, mixinfo->controls[i].control_index)) { debug("simple mixer parser failed parsing ctrl scaler tag, ret: '%s'", buf); goto out; } } sm = new SimpleMixer(control_cb, cb_handle, mixinfo); if (sm != nullptr) { mixinfo = nullptr; debug("loaded mixer with %d input(s)", inputs); } else { debug("could not allocate memory for mixer"); } out: if (mixinfo != nullptr) { free(mixinfo); } return sm; }