void Webserver::GetStatusResponse(uint8_t type) { GCodes *gc = reprap.GetGCodes(); if (type == 1) { // New-style status request // Send the printing/idle status char ch = (reprap.IsStopped()) ? 'S' : (gc->PrintingAFile()) ? 'P' : 'I'; snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"status\":\"%c\",\"heaters\":", ch); // Send the heater temperatures ch = '['; for (int8_t heater = 0; heater < HEATERS; heater++) { sncatf(jsonResponse, ARRAY_UPB(jsonResponse), "%c\%.1f", ch, reprap.GetHeat()->GetTemperature(heater)); ch = ','; } // Send XYZ and extruder positions float liveCoordinates[DRIVES + 1]; reprap.GetMove()->LiveCoordinates(liveCoordinates); strncat(jsonResponse, "],\"pos\":", ARRAY_UPB(jsonResponse)); // announce the XYZ position ch = '['; for (int8_t drive = 0; drive < AXES; drive++) { sncatf(jsonResponse, ARRAY_UPB(jsonResponse), "%c%.2f", ch, liveCoordinates[drive]); ch = ','; } sncatf(jsonResponse, ARRAY_UPB(jsonResponse), "],\"extr\":"); // announce the extruder positions ch = '['; for (int8_t drive = AXES; drive < DRIVES; drive++) // loop through extruders { sncatf(jsonResponse, ARRAY_UPB(jsonResponse), "%c%.3f", ch, gc->GetExtruderPosition(drive - AXES)); ch = ','; } strncat(jsonResponse, "]", ARRAY_UPB(jsonResponse)); // Send the speed and extruder override factors sncatf(jsonResponse, ARRAY_UPB(jsonResponse), ",\"sfactor\":%.2f,\"efactor:\":", gc->GetSpeedFactor() * 100.0); const float *extrusionFactors = gc->GetExtrusionFactors(); for (unsigned int i = 0; i < DRIVES - AXES; ++i) { sncatf(jsonResponse, ARRAY_UPB(jsonResponse), "%c%.2f", (i == 0) ? '[' : ',', extrusionFactors[i] * 100.0); } strncat(jsonResponse, "]", ARRAY_UPB(jsonResponse)); }
void crtc_print(char* buffer, unsigned size, const adv_crtc* crtc) { const char* flag1 = crtc_is_nhsync(crtc) ? " -hsync" : " +hsync"; const char* flag2 = crtc_is_nvsync(crtc) ? " -vsync" : " +vsync"; const char* flag3 = crtc_is_doublescan(crtc) ? " doublescan" : ""; const char* flag4 = crtc_is_interlace(crtc) ? " interlace" : ""; *buffer = 0; if (strchr(crtc->name, ' ')!=0) sncatf(buffer, size, "\"%s\"", crtc->name); else sncatf(buffer, size, "%s", crtc->name); sncatf(buffer, size, " %g %d %d %d %d %d %d %d %d%s%s%s%s", (double)crtc->pixelclock / 1E6, crtc->hde, crtc->hrs, crtc->hre, crtc->ht, crtc->vde, crtc->vrs, crtc->vre, crtc->vt, flag1, flag2, flag3, flag4 ); }
adv_error monitor_conversion_legacy(adv_conf* context) { char buffer[1024]; adv_error p_error; adv_error h_error; adv_error v_error; const char* p; const char* h; const char* v; char* ps; char* hs; char* vs; char c; int pi,hi,vi; /* LEGACY support of old device_video_p/h/vclock format */ p_error = conf_string_section_get(context, "", "device_video_pclock", &p); h_error = conf_string_section_get(context, "", "device_video_hclock", &h); v_error = conf_string_section_get(context, "", "device_video_vclock", &v); /* check if all are missing */ if (p_error != 0 && h_error != 0 && v_error != 0) return 0; /* partially missing */ if (p_error != 0 || h_error != 0 || v_error != 0) { error_set("Missing options 'device_video_p/h/vclock'"); return -1; } buffer[0] = 0; ps = strdup(p); hs = strdup(h); vs = strdup(v); /* set the new format */ pi = 0; sskip(&pi, ps, " "); while (ps[pi]) { const char* pt; pt = stoken(&c, &pi, ps, ",", " "); hi = 0; sskip(&hi, hs, " "); while (hs[hi]) { const char* ht; ht = stoken(&c, &hi, hs, ",", " "); vi = 0; sskip(&vi, vs, " "); while (vs[vi]) { const char* vt; vt = stoken(&c, &vi, vs, ",", " "); if (*buffer != 0) sncat(buffer, sizeof(buffer), " ; "); sncatf(buffer, sizeof(buffer), "%s / %s / %s", pt, ht, vt); sskip(&vi, vs, " "); } sskip(&hi, hs, " "); } sskip(&pi, ps, " "); } free(ps); free(hs); free(vs); conf_string_set(context, "", "device_video_clock", buffer); /* remove the old copy */ conf_remove(context, "", "device_video_pclock"); conf_remove(context, "", "device_video_hclock"); conf_remove(context, "", "device_video_vclock"); return 0; }
// Get the Json response for this command. // 'value' is null-terminated, but we also pass its length in case it contains embedded nulls, which matter when uploading files. bool Webserver::GetJsonResponse(const char* request, const char* key, const char* value, size_t valueLength) { bool found = true; // assume success bool keepOpen = false; // assume we don't want to persist the connection if (StringEquals(request, "status")) // new style status request { GetStatusResponse(1); } else if (StringEquals(request, "poll")) // old style status request { GetStatusResponse(0); } else if (StringEquals(request, "gcode") && StringEquals(key, "gcode")) { LoadGcodeBuffer(value); snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"buff\":%u}", GetReportedGcodeBufferSpace()); } else if (StringEquals(request, "upload_begin") && StringEquals(key, "name")) { CancelUpload(); FileStore *f = platform->GetFileStore("0:/", value, true); if (f != NULL) { fileBeingUploaded.Set(f); uploadState = uploadOK; } else { uploadState = uploadError; } GetJsonUploadResponse(); } else if (StringEquals(request, "upload_data") && StringEquals(key, "data")) { if (uploadState == uploadOK) { uploadPointer = value; uploadLength = valueLength; } GetJsonUploadResponse(); keepOpen = true; } else if (StringEquals(request, "upload_end") && StringEquals(key, "size")) { // Write the remaining data if (uploadLength != 0) { if (!fileBeingUploaded.Write(uploadPointer, uploadLength)) { uploadState = uploadError; } } uploadPointer = NULL; uploadLength = 0; if (uploadState == uploadOK && !fileBeingUploaded.Flush()) { uploadState = uploadError; } // Check the file length is as expected if (uploadState == uploadOK && fileBeingUploaded.Length() != strtoul(value, NULL, 10)) { uploadState = uploadError; } // Close the file if (!fileBeingUploaded.Close()) { uploadState = uploadError; } GetJsonUploadResponse(); if (uploadState != uploadOK && strlen(filenameBeingUploaded) != 0) { platform->GetMassStorage()->Delete("0:/", filenameBeingUploaded); } filenameBeingUploaded[0] = 0; } else if (StringEquals(request, "upload_cancel")) { CancelUpload(); snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"err\":%d}", 0); } else if (StringEquals(request, "delete") && StringEquals(key, "name")) { bool ok = platform->GetMassStorage()->Delete("0:/", value); snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"err\":%d}", (ok) ? 0 : 1); } else if (StringEquals(request, "files")) { const char* dir = (StringEquals(key, "dir")) ? value : platform->GetGCodeDir(); const char* fileList = platform->GetMassStorage()->FileList(dir, false); snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"files\":[%s]}", fileList); } else if (StringEquals(request, "fileinfo") && StringEquals(key, "name")) { unsigned long length; float height, filament, layerHeight; char generatedBy[50]; bool found = GetFileInfo(value, length, height, filament, layerHeight, generatedBy, ARRAY_SIZE(generatedBy)); if (found) { snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"err\":0,\"size\":%lu,\"height\":%.2f,\"filament\":%.1f,\"layerHeight\":%.2f,\"generatedBy\":\"%s\"}", length, height, filament, layerHeight, generatedBy); } else { snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"err\":1}"); } } else if (StringEquals(request, "name")) { snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"myName\":\""); size_t j = strlen(jsonResponse); for (size_t i = 0; i < ARRAY_SIZE(myName) - 1; ++i) { char c = myName[i]; if (c < ' ') // if null terminator or bad character break; if (c == '"' || c == '\\') { // Need to escape the quote-mark or backslash for JSON jsonResponse[j++] = '\\'; } jsonResponse[j++] = c; } jsonResponse[j++] = '"'; jsonResponse[j++] = '}'; jsonResponse[j] = 0; } else if (StringEquals(request, "password") && StringEquals(key, "password")) { CheckPassword(value); snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"password\":\"%s\"}", (gotPassword) ? "right" : "wrong"); } else if (StringEquals(request, "axes")) { strncpy(jsonResponse, "{\"axes\":", ARRAY_UPB(jsonResponse)); char ch = '['; for (int8_t drive = 0; drive < AXES; drive++) { sncatf(jsonResponse, ARRAY_UPB(jsonResponse), "%c%.1f", ch, platform->AxisTotalLength(drive)); ch = ','; } strncat(jsonResponse, "]}", ARRAY_UPB(jsonResponse)); } else if (StringEquals(request, "connect")) { CancelUpload(); GetStatusResponse(1); } else { found = false; } JsonReport(found, request); return keepOpen; }
void run(void) { char msg[1024]; char new_msg[1024]; int i, j, k; target_clock_t last; printf("Press Break to exit\n"); signal(SIGINT, sigint); last = target_clock(); msg[0] = 0; while (!done) { new_msg[0] = 0; for (i = 0; i < joystickb_count_get(); ++i) { if (i != 0) sncat(new_msg, sizeof(new_msg), "\n"); snprintf(new_msg + strlen(new_msg), sizeof(new_msg) - strlen(new_msg), "joy %d, [", i); for (j = 0; j < joystickb_button_count_get(i); ++j) { if (joystickb_button_get(i, j)) sncat(new_msg, sizeof(new_msg), "_"); else sncat(new_msg, sizeof(new_msg), "-"); } sncat(new_msg, sizeof(new_msg), "], "); for (j = 0; j < joystickb_stick_count_get(i); ++j) { for (k = 0; k < joystickb_stick_axe_count_get(i, j); ++k) { char digital; if (joystickb_stick_axe_digital_get(i, j, k, 0)) digital = '\\'; else if (joystickb_stick_axe_digital_get(i, j, k, 1)) digital = '/'; else digital = '-'; sncatf(new_msg, sizeof(new_msg), " %d/%d [%6d %c]", j, k, joystickb_stick_axe_analog_get(i, j, k), digital); } } sncat(new_msg, sizeof(new_msg), " ["); for (j = 0; j < joystickb_rel_count_get(i); ++j) { if (j != 0) sncat(new_msg, sizeof(new_msg), "/"); sncatf(new_msg, sizeof(new_msg), "%d", joystickb_rel_get(i, j)); } sncat(new_msg, sizeof(new_msg), "]"); } if (strcmp(msg, new_msg) != 0) { target_clock_t current = target_clock(); double period = (current - last) * 1000.0 / TARGET_CLOCKS_PER_SEC; last = current; sncpy(msg, sizeof(msg), new_msg); printf("%s (%4.0f ms)\n", msg, period); } os_poll(); joystickb_poll(); target_yield(); } }