int rr_dev_resend (rr_dev dev, unsigned long lineno, const char *reply, size_t nbytes) { int resent = 0; blocknode *node; /* sent cache slot 0 is most recent */ while (1) { if (!(node = rr_dev_pop_from_queue (dev, RR_PRIO_SENTCACHE))) break; rr_dev_log (dev, RR_DEBUG_HIGH, "pop sent node line %d '%s' (%d bytes)\n", (int)node->line, node->block, node->blocksize); if (node->line >= lineno) { rr_dev_prepend_to_queue (dev, RR_PRIO_RESEND, node); resent++; } else { /* put it back and look elsewhere */ rr_dev_prepend_to_queue (dev, RR_PRIO_SENTCACHE, node); break; } } if (resent == 0) { /* Perhaps line is in the resend queue, and we got an: * rs: 3 * rs: 6 * type sequence so try peel forward the resend queue. */ while (1) { if (!(node = rr_dev_pop_from_queue (dev, RR_PRIO_RESEND))) break; rr_dev_log (dev, RR_DEBUG_HIGH, "pop resend node line %d '%s' (%d bytes)\n", (int)node->line, node->block, node->blocksize); if (node->line < lineno) { rr_dev_prepend_to_queue (dev, RR_PRIO_SENTCACHE, node); resent++; } else { /* put it back and give up */ rr_dev_prepend_to_queue (dev, RR_PRIO_RESEND, node); break; } } if (resent == 0) { rr_dev_log (dev, RR_DEBUG_ALWAYS, "re-send request for unknown (too old) line %ld from cache size %d\n", lineno, dev->sendsize[RR_PRIO_SENTCACHE]); rr_dev_emit_error (dev, RR_E_UNCACHED_RESEND, reply, nbytes); } } dev->send_next = 1; dev->wait_wr_cb (dev, 1, dev->wait_wr_cl); return 0; }
int fived_handle_reply (rr_dev dev, const char *reply, size_t nbytes) { if (!strncasecmp ("ok", reply, 2)) { rr_dev_handle_ok (dev); /* Parse values */ char *i; for (i = (char*)reply + 2; i < reply + nbytes; ++i) { if (isspace (*i)) continue; switch (toupper (*i)) { case 'T': float_reply (dev, &i, RR_NOZZLE_TEMP); break; case 'B': float_reply (dev, &i, RR_BED_TEMP); break; case 'C': break; case 'X': float_reply (dev, &i, RR_X_POS); break; case 'Y': float_reply (dev, &i, RR_Y_POS); break; case 'Z': float_reply (dev, &i, RR_Z_POS); break; case 'E': float_reply (dev, &i, RR_E_POS); break; default: break; //return rr_dev_emit_error (dev, RR_E_UNKNOWN_REPLY, reply, nbytes); } } return 0; } else if (!strncasecmp ("rs", reply, 2) || !strncasecmp ("resend", reply, 6)) { /* check where the line number starts */ size_t n_start = strcspn (reply, "123456789"); if (n_start) { long long lineno = strtoll (reply + n_start, NULL, 10); if (dev->sendsize[RR_PRIO_SENTCACHE] + dev->sendsize[RR_PRIO_RESEND] <= 1) { /* * oh dear - most likely we re-connected to a device that * had problems mid-flow, now we need to re-send the * line-number reset as if it was this line-no it is asking * for a re-send of, or there will be no peace */ rr_dev_log (dev, RR_DEBUG_ALWAYS, "resetting confused firmware with synthetic resend of line %d\n", lineno); rr_dev_enqueue_internal (dev, RR_PRIO_HIGH, "M110", 4, lineno); /* re-start the print */ rr_dev_resend (dev, 0, "synthetic restart", 16); return rr_dev_emit_error (dev, RR_E_UNSENT_RESEND, reply, nbytes); } return rr_dev_resend (dev, lineno, reply, nbytes); } else return rr_dev_emit_error (dev, RR_E_MALFORMED_RESEND_REQUEST, reply, nbytes); } else if (!strncmp("!!", reply, 2)) { return rr_dev_emit_error (dev, RR_E_HARDWARE_FAULT, reply, nbytes); } else if (!strncasecmp ("start", reply, 5)) { return rr_dev_handle_start (dev); } else return rr_dev_emit_error (dev, RR_E_UNKNOWN_REPLY, reply, nbytes); }