-->
Page 1 of 2

Streaming large files to Android?

PostPosted: Thu Jan 28, 2016 11:12 pm
by Vinylon
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:

Code: Select allvoid 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 allctx: 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<<<

Re: Streaming large files to Android?

PostPosted: Fri Jan 29, 2016 4:12 am
by schufti
would be interesting if it still crashes if you do it like this
Code: Select all  while (progress < fSize) {
    readResult = file.read(responseBlob, fChunk);
    delay(0); // or yield();
    server.client().write(responseBlob, fChunk);
    delay(10);
    progress += fChunk;


it might be either a wd timeout or an overflow of some internal buffering in the write routine.
maybe it would help to check (if possible?) status (or as in example just add delay) before calling write with the next Chunk.

Re: Streaming large files to Android?

PostPosted: Fri Jan 29, 2016 1:21 pm
by Vinylon
I did try adding a short delay and while it seems to prevent the chip from crashing outright, the file still isn't delivered successfully. I'm wondering if my phone is cutting off the connection early or failing to ACK or something - sometimes it will start downloading a file, but it doesn't seem to read the headers; the download is generally named 'Untitled', and it fails or hangs immediately after starting.

Re: Streaming large files to Android?

PostPosted: Fri Jan 29, 2016 2:34 pm
by schufti
This may definitely a problem of the mobile browser. I quite often run into problems downloading various files with mobile browsers. While desktop versions seldom make problems with "right click an save as" it seems to be a lottery with mobile versions ...