adafruit/Adafruit_CC3000_Library

WebClient example crashes on large file downloads

vicatcu opened this issue · 13 comments

Open the WebClient example from the Adafruit_CC3000_Library, set it up for your network credentials, and use:

define WEBSITE "45.55.159.249"

define WEBPAGE "/test.hex"

I expect it will start downloading and printing out the file, but will eventually halt and timeout before the end of the file is reached. Loading the same thing in your web browser works without a hitch: http://45.55.159.249/test.hex.

I want to share that I've worked around this, but it's super dirty. First I took out the Serial.print in the www.read loop. Second I used www.read(mybuffer, 255) instead of c = www.read(). Third I declare mybuffer to be 512 bytes (not the 255 you'd think it needs to be). Yikes. I'm not sure it matters, but I'm also using (in utility/cc3000_commmon.h):

#define CC3000_RX_BUFFER_SIZE   (CC3000_MAXIMAL_RX_SIZE)
#define CC3000_TX_BUFFER_SIZE   (CC3000_MAXIMAL_TX_SIZE)

I'm hoping some of the more software-inclined members among the community can use this information to come up with a real fix.

An additional tidbit from more testing. If I make the www.read(mybuffer, 256) instead of www.read(mybuffer,255) it goes back to failing hard. That makes me think there is a lingering data type / pointer type issue in the guts somewhere, but nothing jumps out at me.

I would surely appreciate it if any users of the library could at least corroborate or refute my experience.

Just had a chance to take a look and I can't repro a lockup or timeout while downloading the data. For example here's a response I see:

Hello, CC3000!

Free RAM: 1150

Initializing...

Attempting to connect to tony-2.4
Connected!
Request DHCP

IP Addr: 192.168.1.112
Netmask: 255.255.255.0
Gateway: 192.168.1.1
DHCPsrv: 192.168.1.1
DNSserv: 192.168.1.1
45.55.159.249 -> 45.55.159.249-------------------------------------
HTTP/1.1 200 OK
Date: Tue, 07 Apr 2015 06:34:10 GMT
Server: Apache/2.4.7 (Ubuntu)
Last-Modified: Thu, 26 Mar 2015 17:25:53 GMT
ETag: "12d0-512344ed03ea3"
Accept-Ranges: bytes
Content-Length: 4816

:100000000C9494000C94B3000C94B3000C94B300C3
:100010000C94B3000C94B3000C94B3000C94B30094
:100020000C94B3000C94B3000C94B3000C94B30084
:100030000C94B3000C94B3000C94B3000C94B30074
:100040000C94B3000C94B3000C94E8010C94B3002E
:100050000C94B3000C94B3000C94B3000C94B30054
:100060000C94B3000C94B3000C94B3000C94B30044
:100070000C94B3000C94B3000C94B3000C94B30034
:100080000C94B3000C94B3000C94B3005E016101B6
:100090005401580178017801650169016F0173010C
:1000A000EB02F002F502FF022D032D0309031103F9
:1000B00019032303000000000103080004020700E5
:1000C000090A00000000000000000000000000001D
:1000D00000000000010204080820400810108020E1
:1000E0004080100420408002010104020102040843
:1000F00010204080040404040204040304020402E7
:1001000002020303030303030302020201010101CC
:100110000101010100002200250028002B00000041
:100120002100240027002A0011241FBECFEFD0E4B5
:10013000DEBFCDBF11E0A0E0B1E0ECE9F6E000E009
:100140000BBF02C007900D92AE30B107D9F721E086
:10015000AEE0B1E001C01D92A931B207E1F70E9403
:1001600037030C944C030C94000061E08091020171
:100170000C94790160910E0170910F018091020140
:100180000E94C502209100013091010180910E0171
:1001900090910F01820F931F90930F0180930E0196
:1001A000009719F08F3F910539F431952195310968
:1001B00030930101209300016EE170E080E090E057
:1001C0000C945502EF92FF920F931F93CF93DF93FE
:1001D000CDB7DEB72A970FB6F894DEBF0FBECDBFFE
:1001E00061E08AE00E94B20161E084E00E94B20115
:1001F00060E088E00E94790161E088E00E94B2013D
:1002000060E08CE00E94790161E08CE00E94B20124
:1002100061E089E00E94B20160E086E00E94B201E4
:1002200061E085E10E94B20161E080E10E94B201DB
:1002300061E087E00E94B20161E08FE00E94B201BC
:1002400061E08EE00E94B2018AE0E4E0F1E0DE01CC
:10025000119601900D928A95E1F78E010F5F1F4F65
:100260007E0188E0E80EF11C61E0F80181918F01C8
:100270000E9479010E151F05B9F72A960FB6F8945A
:10028000DEBF0FBECDBFDF91CF911F910F91FF90C9
:10029000EF90089590E0FC013197EA30F10540F5C8
:1002A000EA5BFF4F0C944603809180008F7703C078
:1002B000809180008F7D80938000089584B58F7732
:1002C00002C084B58F7D84BD08958091B0008F7782
:1002D00003C08091B0008F7D8093B000089580911D
:1002E00090008F7703C0809190008F7D8093900065
:1002F0000895CF93DF9390E0FC01EC52FF4F2491DF
:10030000FC01EC50FF4F8491882349F190E0880F65
:10031000991FFC01E25EFE4FA591B4918C5E9E4F49
:10032000FC01C591D4919FB7611108C0F8948C91DC
:10033000209582238C93888182230AC0623051F4F5
:10034000F8948C91322F309583238C938881822B63
:10035000888304C0F8948C91822B8C939FBFDF918B
:10036000CF9108950F931F93CF93DF931F92CDB733
:10037000DEB7282F30E0F901EC54FF4F8491F901EA
:10038000EC52FF4F1491F901EC50FF4F0491002300
:10039000C9F0882321F069830E944A016981E02F16
:1003A000F0E0EE0FFF1FEC5EFE4FA591B4919FB7FA
:1003B000F8948C91611103C01095812301C0812BA9
:1003C0008C939FBF0F90DF91CF911F910F91089554
:1003D0001F920F920FB60F9211242F933F938F937A
:1003E0009F93AF93BF938091110190911201A091BF
:1003F0001301B09114013091100123E0230F2D3728
:1004000020F40196A11DB11D05C026E8230F029618
:10041000A11DB11D20931001809311019093120131
:10042000A0931301B09314018091150190911601CE
:10043000A0911701B09118010196A11DB11D8093E3
:10044000150190931601A0931701B0931801BF9165
:10045000AF919F918F913F912F910F900FBE0F9071
:100460001F9018953FB7F89480911501909116014F
:10047000A0911701B091180126B5A89B05C02F3F88
:1004800019F00196A11DB11D3FBF6627782F892F56
:100490009A2F620F711D811D911D42E0660F771F1B
:1004A000881F991F4A95D1F70895CF92DF92EF9256
:1004B000FF92CF93DF936B017C010E943202EB012C
:1004C000C114D104E104F10489F00E9436030E94B2
:1004D00032026C1B7D0B683E734090F381E0C81ABA
:1004E000D108E108F108C851DC4FEACFDF91CF9184
:1004F000FF90EF90DF90CF900895789484B582605C
:1005000084BD84B5816084BD85B5826085BD85B5B7
:10051000816085BDEEE6F0E0808181608083E1E866
:10052000F0E010828081826080838081816080839E
:10053000E0E8F0E0808181608083E1EBF0E08081A1
:1005400084608083E0EBF0E0808181608083E1E97A
:10055000F0E0808182608083808181608083E0E937
:10056000F0E0808181608083EAE7F0E08081846050
:1005700080838081826080838081816080838081AC
:10058000806880831092C10008951F93CF93DF93FA
:10059000182FEB0161E00E947901209711F460E0CF
:1005A00004C0CF3FD10539F461E0812FDF91CF91B5
:1005B0001F910C94B201E12FF0E0EC54FF4F4491F5
:1005C00050E0FA013197EA30F10508F046C0E05BEF
:1005D000FF4F0C94460384B5806884BDC7BD42C0FC
:1005E00084B5806284BDC8BD3DC0809180008068B4
:1005F00080938000D0938900C093880033C080919D
:100600008000806280938000D0938B00C0938A002A
:1006100029C08091B00080688093B000C093B3007F
:1006200021C08091B00080628093B000C093B4007C
:1006300019C080919000806880939000D0939900B9
:10064000C09398000FC080919000806280939000CA
:10065000D0939B00C0939A0005C0C038D1050CF020
:10066000A3CF9DCFDF91CF911F91089508950E9450
:100670007D020E94E2000E94B500C0E0D0E00E942E
:10068000BA002097E1F30E940000F9CFEE0FFF1FA0
:0C0690000590F491E02D0994F894FFCF40
:0E069C000500060006070E0F101517090B0DBE
:00000001FF
-------------------------------------


Disconnecting

If you grab the latest library does it still repro for you too? I did just make one change to help the reliability of send calls but I don't think it would affect much here. Curious to see though if it helps.

If you're still hitting issues, then yeah I don't think the webclient example is really the best for downloading larger amounts of data. It processes things a character at a time so it's going to be somewhat slow and it wouldn't surprise me if fast server pushes out data much quicker than the sketch & cc3000 can handle. There's probably only so much data the cc3k can buffer up before it gives up. Reading a big buffer at a time would definitely help.

@tdicola hey sorry I had replaced that file with a much smaller one. I've just put the "large" file back on the webserver. Please could you give it another try on your end? Sorry for the mix-up there.

@tdicola I just tried with the latest library updates and it still quits the download prematurely. Are you able to get the same result? The point at which it quits is not predictable. I've seen it get to the line starting with ":102940" then retrying right after that it gets to the line starting with ":102530"...

@tdicola just checking in again here to see if you've had a chance to try and reproduce the bug.

@tdicola Hope you're well! Have you (or has anyone) had a chance to take a look at this? It's been 21 days since a comment from someone other than me :-(. if nothing else, it would be nice if I could get confirmation that it's a real reproducible problem. Pretty please? With sugar on top? I understand how busy things can get, but this should really take very little effort.

Sorry was a bit busy and didn't have time to look at this again until now. Yeah I repro it too but it doesn't look like anything is getting stuck in the library. I swapped over the main loop to read into a buffer instead of doing it character by character:

  while (www.connected() && (millis() - lastRead < IDLE_TIMEOUT_MS)) {
    while (www.available()) {
      //char c = www.read();
      //Serial.print(c);
      //lastRead = millis();
      char received[80] = {0};  // Don't make this buffer larger than ~90 chars or the CC3k buffer will overflow and lock up!
      if (www.read(received, sizeof(received)-1) > 0) {
        Serial.print(received);
        lastRead = millis(); 
      }
    }
  }

This gets me about as far this point:

:102B100000000000000000000000000000000000B5
:102B200000000000000000000000000000000000A5
:102B30000000000000000000000000000000000095
:102B4000000000000000000000000000000000008-------------------------------------


Disconnecting

The fact that the code is stopping and getting to the disconnecting point means that the www.available() function is returning no more data available to read (and this is just calling the CC3k socket select() API internally). After the web client code spins in the loop with no more data available to read for a few seconds it times out and stops the sketch. So the program isn't getting stuck in the Arduino library, unfortunately it's the CC3k itself that's returning the result that no more data can be read.

I think this could be caused by a few things:

  • The server is closing the connection before the sketch can read all the data. I remember seeing complaints about this in TI's CC3k forum, that if a socket is closed you can't read any data from it anymore. However the WebClient sketch is careful to use HTTP/1.1 so that the server should keep the connection open until the sketch decides to close it.
  • Some kind of bug inside the CC3k's firmware (unfortunately I'm using the latest firmware, 1.14). I noticed the sketch starts to slow down and spit out data in chunks before it stops. This makes me think something is going on inside the CC3k's firmware like it's hitting some race condition, exhausting buffers, or something similar which is causing it to eventually give up or deadlock in some way so that it stops returning data.

Unfortunately this doesn't fix the problem, but at least I do repro the issue and it doesn't appear to be anything in our control with the library. I think the best you could do is post on TI's CC3k forums to see if anyone there can help give support on it.

Thanks @tdicola, I appreciate you looking into it, and glad it's not just me. Your description matches mine very closely, things appear to be going great until they're not, and before the (non-deterministic) end game, there are some final sputters of output with increasing time between them (if you make the timeout "infinite" you can see that more clearly. I'll see what I can sniff out in the TI forum and post back if I find anything of interest.

I've started a thread on e2e for anyone following along.
https://e2e.ti.com/support/wireless_connectivity/f/851/t/430075

To add a wrinkle to the story, the reliability of my 'workaround' (using a buffered reading pattern) appears to work on some networks, but not on others... I haven't been able to characterize what's going on at the TCP/IP level between client and server as of yet - advice on how to go about that would be welcome.

@tdicola looks like I actually got a bite on E2E. There's a suggestion that this might be related to issue #122 ... what do you think?

@tdicola I posted a packet capture from the perspective of the server to the E2E thread, care to take a look and weigh in? You can open the file in WireShark which parses all the packets. It contains all the packet traffic (coming and going) at the server to/from the CC3000 on port 80...