Streaming large files to Android?
Posted: Thu Jan 28, 2016 11:12 pm
Hey everyone!
I'm working on a simple SD card file server and it's working pretty well, but I'm having trouble getting Android devices to receive files. Any help would be really appreciated!
Basically, my approach is to run an access point with a DNS server that redirects requests to a landing page containing the SD card's directory structure with links to the download the files. This approach works well on a machine running Linux Mint, but I haven't been able to successfully send a file to a mobile device. I've only tested it on Android though, so I'm not sure whether the same thing happens on iOS.
I didn't want to load the whole file at once since memory is so scarce, so I wound up just looking at how the WebServer library constructs its response, and sending the data one block at a time with the client's write() method. Specifically:
This works fine with my laptop; I can connect to the network, load a page like 'http://somewhere', and download the file without any issues. But on my phone, the file doesn't download as the chip sends the data. Sometimes the ESP module crashes partway through sending the data, too. Any ideas about what could be causing this? Thanks in advance!
Edit: Here's what gets printed in the serial monitor when the chip crashes as my phone tries to download from it. Unfortunately, it's Greek to me:
I'm working on a simple SD card file server and it's working pretty well, but I'm having trouble getting Android devices to receive files. Any help would be really appreciated!
Basically, my approach is to run an access point with a DNS server that redirects requests to a landing page containing the SD card's directory structure with links to the download the files. This approach works well on a machine running Linux Mint, but I haven't been able to successfully send a file to a mobile device. I've only tested it on Android though, so I'm not sure whether the same thing happens on iOS.
I didn't want to load the whole file at once since memory is so scarce, so I wound up just looking at how the WebServer library constructs its response, and sending the data one block at a time with the client's write() method. Specifically:
Code: Select all
void sendRawFile(String fn, File file) {
int fSize = file.fileSize();
String response = "HTTP/1.1 200 OK\r\n";
// Test with ebooks for now.
response += "Content-Type: application/x-mobipocket-ebook\r\n";
response += "Content-Disposition: attachment; filename=" + fn + "\r\n";
response += "Connection: keep-alive\r\n";
response += "Access-Control-Allow-Origin: *\r\n";
response += "Content-Length: ";
response += fSize;
response += "\r\n";
response += "\r\n";
server.client().setNoDelay(true);
server.sendContent(response);
int readResult = 0;
// SD card block size.
int fChunk = 512;
int progress = 0;
char responseBlob[fChunk];
// In case the file doesn't get re-opened before being dl'd again,
// reset the position after it's read.
FatPos_t fileStart;
file.getpos(&fileStart);
while (progress < fSize) {
readResult = file.read(responseBlob, fChunk);
server.client().write(responseBlob, fChunk);
progress += fChunk;
if (progress % 16384 == 0) {
Serial.println(progress);
}
}
file.setpos(&fileStart);
}
This works fine with my laptop; I can connect to the network, load a page like 'http://somewhere', and download the file without any issues. But on my phone, the file doesn't download as the chip sends the data. Sometimes the ESP module crashes partway through sending the data, too. Any ideas about what could be causing this? Thanks in advance!
Edit: Here's what gets printed in the serial monitor when the chip crashes as my phone tries to download from it. Unfortunately, it's Greek to me:
Code: Select all
ctx: cont
sp: 3ffeb3f0 end: 3ffeb9d0 offset: 01b0
>>>stack>>>
3ffeb5a0: 3ffea8d4 3ffeb82d 3ffe9d9c 4020710b
3ffeb5b0: 00000200 00000011 3ffe9d9c 40207204
3ffeb5c0: 002b6800 00000001 3ffe8e33 00000000
3ffeb5d0: 3ffeb8c0 3ffeb630 3ffe9d9c 402073d2
3ffeb5e0: 3ffeb8d0 3ffeb8c0 00000200 40202a2b
3ffeb5f0: 3ffeb8c0 3ffeb8c0 00000200 4020b038
3ffeb600: 00000200 3ffeb630 00000000 4020e0f8
3ffeb610: 00095600 3ffeb8c0 3ffe9ddc 3ffeb830
3ffeb620: 00095800 3ffeb8c0 3ffe9ddc 4020264b
3ffeb630: 203cb1fd bd0f5998 9dc80c85 5a604813
3ffeb640: 1c728238 9267a2af 6ad188c9 3cf3f92a
3ffeb650: cb8452b2 0c08b99c f2fee554 42b0cfb0
3ffeb660: c1330a7f 4a2366e0 dcac6fc7 ff1d1097
3ffeb670: 8fb21214 fbf94618 3488db48 bd5e61a0
3ffeb680: 5550adc8 4f0b48fa b89be0cc dbf63005
3ffeb690: 7b644b59 a70eb203 3dd26c18 18422d57
3ffeb6a0: ab44c11d 00397794 fc3863de b25a680c
3ffeb6b0: 7396bbc4 bf90ca73 58e48a09 b4847852
3ffeb6c0: 248a119d b8837e57 0df7d0f9 178924e3
3ffeb6d0: 8dd80507 7326563d 0f0412d6 89ebb2a5
3ffeb6e0: b65741d0 58ac47f6 0be2b734 b44f4a1b
3ffeb6f0: 9bd4784f f7d4ff55 4ea61eed d59da74b
3ffeb700: 7b3d5265 ae08aa8d 84f666bb 474264a5
3ffeb710: 005f5a5e 6fb3c7b7 4f709148 0c212627
3ffeb720: 87868652 1654deee 9267c1cb 5a95ef24
3ffeb730: 911eba43 c08eb6ef ffb512be 1fe792d2
3ffeb740: b52beff4 7635b2db 6c7f7da5 7f5b92e2
3ffeb750: a5966e80 3a0d7a01 5dd710fc 3a075515
3ffeb760: 65f60e5a f9e6418a ae2d07dc 3a1555cc
3ffeb770: 0e129c45 18a9cbd0 7229cdd3 5d05d32f
3ffeb780: 191d35a2 6a2d49f7 9ea272b0 e44d265b
3ffeb790: 10bde633 e1780362 de8f6a68 3505d456
3ffeb7a0: 2860b723 ff20e2e0 2728673d 58e4b580
3ffeb7b0: 12ed0398 01842b89 168254da f7af8173
3ffeb7c0: 2833d2a6 98ef4314 d8ec20d8 ccb896b2
3ffeb7d0: bbf5b4ff db96a035 e9048d5f 584a6ca2
3ffeb7e0: e41e8f58 1d4aea11 ad68434e 95868362
3ffeb7f0: 4f79cdec 61e8e0a0 81c0eee1 00d1c438
3ffeb800: 8564235c 3ad625d5 eef4e220 ddc54852
3ffeb810: 5b0cbd2e 23182989 a87d4c68 2c24becd
3ffeb820: 72c68583 ef284038 7d81aa70 4bcf5553
3ffeb830: 3ffe90f0 00000000 000003e8 3ffe9df8
3ffeb840: 00000000 3fff6110 3ffe90f0 00000000
3ffeb850: 000003e8 3ffeb8e4 3ffeb980 3fff6110
3ffeb860: 3fff6028 000000c7 000000c7 00000000
3ffeb870: 00000000 3ffeba38 3ffeb8e4 4020e656
3ffeb880: 0010137c 3ffeb630 3ffeb8e4 4020e754
3ffeb890: 3fff5aba 3ffe9dc4 3ffe9dc4 3ffe9df8
3ffeb8a0: 3ffe9abc 3ffeba38 3ffe9dc4 402027a9
3ffeb8b0: 3ffe8fb8 00000000 000003e8 00000000
3ffeb8c0: 04010008 00000014 3ffe9b48 00000000
3ffeb8d0: 0000051f 00095800 00000121 0010137c
3ffeb8e0: 000003f4 3fff5d90 0000002a 0000002a
3ffeb8f0: 3fff5a90 00000034 0000002a 4020e656
3ffeb900: 3ffea5c4 3fff59f8 3ffe9dc4 4020da02
3ffeb910: 3fff5468 00000000 00000000 40205612
3ffeb920: 00000039 00000039 3ffe9dc4 40205479
3ffeb930: 00000001 3fff54c8 00000003 00000003
3ffeb940: 3fff5d90 00000048 00000048 40203571
3ffeb950: 3ffe90f0 00000000 000003e8 40203c82
3ffeb960: 00000000 3fff6110 3ffe9dc4 3ffeb9fc
3ffeb970: 3fffdc20 000003e9 3ffe9dc4 40205569
3ffeb980: 3ffe90f0 00000000 000003e8 000110be
3ffeb990: 3ffe9ddc 3fff6110 00000016 40101fe9
3ffeb9a0: 3fffdc20 00000000 3ffeb9f4 40202126
3ffeb9b0: 3fffdc20 00000000 3ffeb9f4 4020184a
3ffeb9c0: 00000000 00000000 3ffea9b0 40100378
<<<stack<<<