void mixer_handle_text(const void *buffer, size_t length) { px4io_mixdata *msg = (px4io_mixdata *)buffer; debug("mixer text %u", length); if (length < sizeof(px4io_mixdata)) return; unsigned text_length = length - sizeof(px4io_mixdata); switch (msg->action) { case F2I_MIXER_ACTION_RESET: debug("reset"); mixer_group.reset(); mixer_text_length = 0; /* FALLTHROUGH */ case F2I_MIXER_ACTION_APPEND: debug("append %d", length); /* check for overflow - this is really fatal */ if ((mixer_text_length + text_length + 1) > sizeof(mixer_text)) return; /* append mixer text and nul-terminate */ memcpy(&mixer_text[mixer_text_length], msg->text, text_length); mixer_text_length += text_length; mixer_text[mixer_text_length] = '\0'; debug("buflen %u", mixer_text_length); /* process the text buffer, adding new mixers as their descriptions can be parsed */ unsigned resid = mixer_text_length; mixer_group.load_from_buf(&mixer_text[0], resid); /* if anything was parsed */ if (resid != mixer_text_length) { debug("used %u", mixer_text_length - resid); /* copy any leftover text to the base of the buffer for re-use */ if (resid > 0) memcpy(&mixer_text[0], &mixer_text[mixer_text_length - resid], resid); mixer_text_length = resid; } break; } }
int mixer_handle_text(const void *buffer, size_t length) { /* do not allow a mixer change while safety off and FMU armed */ if ((r_status_flags & PX4IO_P_STATUS_FLAGS_SAFETY_OFF) && (r_setup_arming & PX4IO_P_SETUP_ARMING_FMU_ARMED)) { return 1; } /* disable mixing, will be enabled once load is complete */ r_status_flags &= ~(PX4IO_P_STATUS_FLAGS_MIXER_OK); /* abort if we're in the mixer - the caller is expected to retry */ if (in_mixer) { return 1; } px4io_mixdata *msg = (px4io_mixdata *)buffer; isr_debug(2, "mix txt %u", length); if (length < sizeof(px4io_mixdata)) { return 0; } unsigned text_length = length - sizeof(px4io_mixdata); switch (msg->action) { case F2I_MIXER_ACTION_RESET: isr_debug(2, "reset"); /* THEN actually delete it */ mixer_group.reset(); mixer_text_length = 0; /* FALLTHROUGH */ case F2I_MIXER_ACTION_APPEND: isr_debug(2, "append %d", length); /* check for overflow - this would be really fatal */ if ((mixer_text_length + text_length + 1) > sizeof(mixer_text)) { r_status_flags &= ~PX4IO_P_STATUS_FLAGS_MIXER_OK; return 0; } /* append mixer text and nul-terminate, guard against overflow */ memcpy(&mixer_text[mixer_text_length], msg->text, text_length); mixer_text_length += text_length; mixer_text[mixer_text_length] = '\0'; isr_debug(2, "buflen %u", mixer_text_length); /* process the text buffer, adding new mixers as their descriptions can be parsed */ unsigned resid = mixer_text_length; mixer_group.load_from_buf(&mixer_text[0], resid); /* if anything was parsed */ if (resid != mixer_text_length) { isr_debug(2, "used %u", mixer_text_length - resid); /* copy any leftover text to the base of the buffer for re-use */ if (resid > 0) { memmove(&mixer_text[0], &mixer_text[mixer_text_length - resid], resid); /* enforce null termination */ mixer_text[resid] = '\0'; } mixer_text_length = resid; } break; } return 0; }
void mixer_handle_text(const void *buffer, size_t length) { /* do not allow a mixer change while outputs armed */ if ((r_status_flags & PX4IO_P_STATUS_FLAGS_OUTPUTS_ARMED)) { return; } px4io_mixdata *msg = (px4io_mixdata *)buffer; isr_debug(2, "mix txt %u", length); if (length < sizeof(px4io_mixdata)) return; unsigned text_length = length - sizeof(px4io_mixdata); switch (msg->action) { case F2I_MIXER_ACTION_RESET: isr_debug(2, "reset"); /* FIRST mark the mixer as invalid */ r_status_flags &= ~PX4IO_P_STATUS_FLAGS_MIXER_OK; /* THEN actually delete it */ mixer_group.reset(); mixer_text_length = 0; /* FALLTHROUGH */ case F2I_MIXER_ACTION_APPEND: isr_debug(2, "append %d", length); /* check for overflow - this would be really fatal */ if ((mixer_text_length + text_length + 1) > sizeof(mixer_text)) { r_status_flags &= ~PX4IO_P_STATUS_FLAGS_MIXER_OK; return; } /* append mixer text and nul-terminate */ memcpy(&mixer_text[mixer_text_length], msg->text, text_length); mixer_text_length += text_length; mixer_text[mixer_text_length] = '\0'; isr_debug(2, "buflen %u", mixer_text_length); /* process the text buffer, adding new mixers as their descriptions can be parsed */ unsigned resid = mixer_text_length; mixer_group.load_from_buf(&mixer_text[0], resid); /* if anything was parsed */ if (resid != mixer_text_length) { /* only set mixer ok if no residual is left over */ if (resid == 0) { r_status_flags |= PX4IO_P_STATUS_FLAGS_MIXER_OK; } else { /* not yet reached the end of the mixer, set as not ok */ r_status_flags &= ~PX4IO_P_STATUS_FLAGS_MIXER_OK; } isr_debug(2, "used %u", mixer_text_length - resid); /* copy any leftover text to the base of the buffer for re-use */ if (resid > 0) memcpy(&mixer_text[0], &mixer_text[mixer_text_length - resid], resid); mixer_text_length = resid; /* update failsafe values */ mixer_set_failsafe(); } break; } }
bool MixerTest::load_mixer(const char *filename, const char *buf, unsigned loaded, unsigned expected_count, const unsigned chunk_size, bool verbose) { /* load the mixer in chunks, like * in the case of a remote load, * e.g. on PX4IO. */ /* load at once test */ unsigned xx = loaded; mixer_group.reset(); mixer_group.load_from_buf(&buf[0], xx); if (expected_count > 0) { ut_compare("check number of mixers loaded", mixer_group.count(), expected_count); } unsigned empty_load = 2; char empty_buf[2]; empty_buf[0] = ' '; empty_buf[1] = '\0'; mixer_group.reset(); mixer_group.load_from_buf(&empty_buf[0], empty_load); if (verbose) { PX4_INFO("empty buffer load: loaded %u mixers, used: %u", mixer_group.count(), empty_load); } ut_compare("empty buffer load", empty_load, 0); /* reset, load in chunks */ mixer_group.reset(); char mixer_text[PX4IO_MAX_MIXER_LENGHT]; /* large enough for one mixer */ unsigned mixer_text_length = 0; unsigned transmitted = 0; unsigned resid = 0; while (transmitted < loaded) { unsigned text_length = (loaded - transmitted > chunk_size) ? chunk_size : loaded - transmitted; /* check for overflow - this would be really fatal */ if ((mixer_text_length + text_length + 1) > sizeof(mixer_text)) { PX4_ERR("Mixer text length overflow for file: %s. Is PX4IO_MAX_MIXER_LENGHT too small? (curr len: %d)", filename, PX4IO_MAX_MIXER_LENGHT); return false; } /* append mixer text and nul-terminate */ memcpy(&mixer_text[mixer_text_length], &buf[transmitted], text_length); mixer_text_length += text_length; mixer_text[mixer_text_length] = '\0'; //fprintf(stderr, "buflen %u, text:\n\"%s\"\n", mixer_text_length, &mixer_text[0]); /* process the text buffer, adding new mixers as their descriptions can be parsed */ resid = mixer_text_length; mixer_group.load_from_buf(&mixer_text[0], resid); /* if anything was parsed */ if (resid != mixer_text_length) { //PX4_INFO("loaded %d mixers, used %u\n", mixer_group.count(), mixer_text_length - resid); /* copy any leftover text to the base of the buffer for re-use */ if (resid > 0) { memmove(&mixer_text[0], &mixer_text[mixer_text_length - resid], resid); /* enforce null termination */ mixer_text[resid] = '\0'; } mixer_text_length = resid; } transmitted += text_length; if (verbose) { PX4_INFO("transmitted: %d, loaded: %d", transmitted, loaded); } } if (verbose) { PX4_INFO("chunked load: loaded %u mixers", mixer_group.count()); } if (expected_count > 0 && mixer_group.count() != expected_count) { PX4_ERR("Load of mixer failed, last chunk: %s, transmitted: %u, text length: %u, resid: %u", mixer_text, transmitted, mixer_text_length, resid); ut_compare("check number of mixers loaded (chunk)", mixer_group.count(), expected_count); } return true; }
int mixer_handle_text(const void *buffer, size_t length) { /* do not allow a mixer change while safety off and FMU armed */ if ((r_status_flags & PX4IO_P_STATUS_FLAGS_SAFETY_OFF) && (r_setup_arming & PX4IO_P_SETUP_ARMING_FMU_ARMED)) { return 1; } /* disable mixing, will be enabled once load is complete */ PX4_ATOMIC_MODIFY_CLEAR(r_status_flags, PX4IO_P_STATUS_FLAGS_MIXER_OK); /* abort if we're in the mixer - the caller is expected to retry */ if (in_mixer) { return 1; } px4io_mixdata *msg = (px4io_mixdata *)buffer; isr_debug(2, "mix txt %u", length); if (length < sizeof(px4io_mixdata)) { return 0; } unsigned text_length = length - sizeof(px4io_mixdata); switch (msg->action) { case F2I_MIXER_ACTION_RESET: isr_debug(2, "reset"); /* THEN actually delete it */ mixer_group.reset(); mixer_text_length = 0; /* FALLTHROUGH */ case F2I_MIXER_ACTION_APPEND: isr_debug(2, "append %d", length); /* check for overflow - this would be really fatal */ if ((mixer_text_length + text_length + 1) > sizeof(mixer_text)) { PX4_ATOMIC_MODIFY_CLEAR(r_status_flags, PX4IO_P_STATUS_FLAGS_MIXER_OK); return 0; } /* check if the last item has been processed - bail out if not */ if (mixer_update_pending) { return 1; } /* append mixer text and nul-terminate, guard against overflow */ memcpy(&mixer_text[mixer_text_length], msg->text, text_length); mixer_text_length += text_length; mixer_text[mixer_text_length] = '\0'; isr_debug(2, "buflen %u", mixer_text_length); /* flag the buffer as ready */ mixer_update_pending = true; break; } return 0; }
void mixer_handle_text(const void *buffer, size_t length) { /* do not allow a mixer change while fully armed */ if (/* FMU is armed */ (r_setup_arming & PX4IO_P_SETUP_ARMING_FMU_ARMED) && /* IO is armed */ (r_status_flags & PX4IO_P_STATUS_FLAGS_ARMED)) { return; } px4io_mixdata *msg = (px4io_mixdata *)buffer; isr_debug(2, "mix txt %u", length); if (length < sizeof(px4io_mixdata)) return; unsigned text_length = length - sizeof(px4io_mixdata); switch (msg->action) { case F2I_MIXER_ACTION_RESET: isr_debug(2, "reset"); /* FIRST mark the mixer as invalid */ r_status_flags &= ~PX4IO_P_STATUS_FLAGS_MIXER_OK; /* THEN actually delete it */ mixer_group.reset(); mixer_text_length = 0; /* FALLTHROUGH */ case F2I_MIXER_ACTION_APPEND: isr_debug(2, "append %d", length); /* check for overflow - this is really fatal */ /* XXX could add just what will fit & try to parse, then repeat... */ if ((mixer_text_length + text_length + 1) > sizeof(mixer_text)) { r_status_flags &= ~PX4IO_P_STATUS_FLAGS_MIXER_OK; return; } /* append mixer text and nul-terminate */ memcpy(&mixer_text[mixer_text_length], msg->text, text_length); mixer_text_length += text_length; mixer_text[mixer_text_length] = '\0'; isr_debug(2, "buflen %u", mixer_text_length); /* process the text buffer, adding new mixers as their descriptions can be parsed */ unsigned resid = mixer_text_length; mixer_group.load_from_buf(&mixer_text[0], resid); /* if anything was parsed */ if (resid != mixer_text_length) { /* ideally, this should test resid == 0 ? */ r_status_flags |= PX4IO_P_STATUS_FLAGS_MIXER_OK; isr_debug(2, "used %u", mixer_text_length - resid); /* copy any leftover text to the base of the buffer for re-use */ if (resid > 0) memcpy(&mixer_text[0], &mixer_text[mixer_text_length - resid], resid); mixer_text_length = resid; } break; } }