I’m trying to add the ability to push an OTA firmware update from a local binary from my app (Spark Pixels)… The app is developed in Eclipse. I’m trying to use a BufferedInputStream, but my syntax isn’t quite right. The JSON response from Particle reports error: “Nothing to do?” Any help would be appreciated.
Here’s my code:
Response putFirmware(URL url, String stringData) {
HttpURLConnection connection = okHttpClient.open(url);
OutputStream out = null;
InputStream in = null;
FileInputStream streamFileInputStream;
BufferedInputStream streamFileBufferedInputStream;
int responseCode = -1;
String responseData = "";
try {
try {
String firmwareFile = "/data/data/kc.spark.pixels.android/files/data/spark_pixels_firmware/spark_pixels.bin";
streamFileInputStream = new FileInputStream(firmwareFile);
streamFileBufferedInputStream = new BufferedInputStream(streamFileInputStream);
byte[] streamFileBytes = new byte[firmwareFile.length()];
int bytesRead = 0;
int totalBytesRead = 0;
connection.setRequestMethod("PUT");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setDoOutput(true);
connection.connect();
out = connection.getOutputStream();
String firstPart = "access_token=<TOKEN>&file_type=binary&file=;
out.write(getStringDataFirstPart(stringData).getBytes(HTTP.UTF_8));
while ((bytesRead = streamFileBufferedInputStream.read(streamFileBytes)) > 0) {
out.write(streamFileBytes, 0, bytesRead);
out.flush();
totalBytesRead += bytesRead;
}
out.close();
responseCode = connection.getResponseCode();
in = connection.getInputStream();
responseData = readAsUtf8String(in);
} finally {
// Clean up.
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
}
} catch (IOException e) {
log.e("Error trying to make " + connection.getRequestMethod() + " request");
}
return new Response(responseCode, responseData);
}
Thanks for your response. I’ll look into trying your suggestions. I did find some other sample code segments from stackoverflow from which I put the following together. However, I see I was a little hasty and didn’t get the bin file setup properly.
Response putFirmware2(URL url, String stringData) {
String param = "value";
String charset = "UTF-8";
InputStream in = null;
int responseCode = -1;
String responseData = "";
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
String CRLF = "\r\n"; // Line separator required by multipart/form-data.
HttpURLConnection connection = okHttpClient.open(url);
BufferedInputStream streamFileBufferedInputStream;
String firmwareFile = "/data/data/kc.spark.pixels.android/files/data/spark_pixels_firmware/spark_pixels.bin";
FileInputStream streamFileInputStream = null;
int bytesRead = 0;
int totalBytesRead = 0;
byte[] streamFileBytes = new byte[firmwareFile.length()];
OutputStream output = null;
PrintWriter writer = null;
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
try {
try{
streamFileInputStream = new FileInputStream(firmwareFile);
streamFileBufferedInputStream = new BufferedInputStream(streamFileInputStream);
output = connection.getOutputStream();
writer = new PrintWriter(new OutputStreamWriter(output, charset), true);
// Send normal param.
writer.append("--" + boundary).append(CRLF);
writer.append("Content-Disposition: form-data; name=\"param\"").append(CRLF);
writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
writer.append(CRLF).append(param).append(CRLF).flush();
// Send binary file.
final String fileName = "spark_pixels.bin";
writer.append("--").append(boundary).append(CRLF)
.append("Content-Disposition: form-data; name=\"")
.append(fileName).append("\"; filename=\"").append(fileName).append("\"").append(CRLF)
.append("Content-Type: ").append("application/octet-stream").append(CRLF)
.append("Content-Transfer-Encoding: binary").append(CRLF)
.append(CRLF);
output.flush(); // Important before continuing with writer!
writer.append(CRLF).flush(); // CRLF is important! It indicates end of boundary.
// End of multipart/form-data.
writer.append("--" + boundary + "--").append(CRLF).flush();
writer.close();
responseCode = connection.getResponseCode();
in = connection.getInputStream();
responseData = readAsUtf8String(in);
} finally {
// Clean up.
if (output != null) {
output.close();
}
if (in != null) {
in.close();
}
}
} catch (IOException e) {
log.e("Error trying to make " + connection.getRequestMethod() + " request");
}
return new Response(responseCode, responseData);
}
I’ll have another go at this routine to see if I can get it to work. Thanks again for pointing me in the right direction.
I didn’t go over it that closely, but I’m pretty sure you’re missing a few lines of code before output.flush(). You need to read the contents of spark_pixels.bin and write them to output, then flush. Other than that, it looks pretty close.