int handle_reply(rr_dev device, const char *reply, size_t nbytes) { if(device->onrecv) { device->onrecv(device, device->onrecv_data, reply, nbytes); } switch(device->proto) { case RR_PROTO_FIVED: return fived_handle_reply(device, reply, nbytes); case RR_PROTO_TONOKIP: return tonokip_handle_reply(device, reply, nbytes); case RR_PROTO_SIMPLE: if(!strncmp("ok", reply, 2) && device->onreply) { device->onreply(device, device->onreply_data, RR_OK, 0); } else if(device->onerr) { device->onerr(device, device->onerr_data, RR_E_UNKNOWN_REPLY, reply, nbytes); } return 0; default: return RR_E_UNSUPPORTED_PROTO; } return 0; }
int tonokip_handle_reply(rr_dev device, const char *reply, size_t nbytes) { if(!strncmp("ok", reply, 2)) { if(device->onreply) { device->onreply(device, device->onreply_data, RR_OK, 0); } } else if(!strncmp("Resend:", reply, 7)) { /* Line number begins 7 bytes in */ return resend(device, atoll(reply + 7), reply, nbytes); } else if(!strncmp("T:", reply, 2)) { if(device->onreply) { char *point; device->onreply(device, device->onreply_data, RR_BED_TEMP, strtof(reply+2, &point)); if(!strncmp("B:", point+1, 2)) { device->onreply(device, device->onreply_data, RR_BED_TEMP, strtof(point+3, NULL)); } } } else { if(device->onerr) { device->onerr(device, device->onerr_data, RR_E_UNKNOWN_REPLY, reply, nbytes); } return RR_E_UNKNOWN_REPLY; } return 0; }
int fived_handle_reply(rr_dev device, const char *reply, size_t nbytes) { if(!strncasecmp("ok", reply, 2)) { if(device->onreply) { device->onreply(device, device->onreply_data, RR_OK, 0); /* Parse values */ char *i; for(i = (char*)reply; i < reply + nbytes; ++i) { switch(toupper(*i)) { case 'T': device->onreply(device, device->onreply_data, RR_NOZZLE_TEMP, strtof(i+2, &i)); break; case 'B': device->onreply(device, device->onreply_data, RR_BED_TEMP, strtof(i+2, &i)); break; case 'C': break; case 'X': device->onreply(device, device->onreply_data, RR_X_POS, strtof(i+2, &i)); break; case 'Y': device->onreply(device, device->onreply_data, RR_Y_POS, strtof(i+2, &i)); break; case 'Z': device->onreply(device, device->onreply_data, RR_Z_POS, strtof(i+2, &i)); break; case 'E': device->onreply(device, device->onreply_data, RR_E_POS, strtof(i+2, &i)); break; default: if(device->onerr) { device->onerr(device, device->onerr_data, RR_E_UNKNOWN_REPLY, reply, nbytes); } break; } } } } 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); /* check if lineno is in the range of sent lines*/ if(lineno < device->lineno && strncmp("-", reply + n_start - 1, 1)) { return resend(device, lineno, reply, nbytes); } else { if(device->onerr) { device->onerr(device, device->onerr_data, RR_E_UNSENT_RESEND, reply, nbytes); } return RR_E_UNSENT_RESEND; } } else { if(device->onerr) { device->onerr(device, device->onerr_data, RR_E_MALFORMED_RESEND_REQUEST, reply, nbytes); } return RR_E_MALFORMED_RESEND_REQUEST; } } else if(!strncmp("!!", reply, 2)) { if(device->onerr) { device->onerr(device, device->onerr_data, RR_E_HARDWARE_FAULT, reply, nbytes); } return RR_E_HARDWARE_FAULT; } else if (!strncasecmp ("start", reply, 5)) { /* * This is non-intuitive. If we reset the controller, when we next send * a command sequence, on the first command we will get a 'start', * meaning we should reset the line number. Problem is we then send * the rest of the command sequence and get another 'start' in mid * flow for some controllers, which gets us out of sync. Ergo we need * to reset the line number with a command each time we hit one of * these. */ rr_reset_lineno (device); } else { if(device->onerr) { device->onerr(device, device->onerr_data, RR_E_UNKNOWN_REPLY, reply, nbytes); } return RR_E_UNKNOWN_REPLY; } return 0; }