I can download PNG using makeImageRequest("https://serverl/png.png"...) but I'd like to not save any file on server.
I can generate PNG in server's memory, but how to return it? I've tried many things but always got 404.
I can download PNG using makeImageRequest("https://serverl/png.png"...) but I'd like to not save any file on server.
I can generate PNG in server's memory, but how to return it? I've tried many things but always got 404.
Could it be the SSL certificates you use with https? Garmin device can be a bit picky, aren't they also tied to a specific IP address?
What if you use a hard coded IP and not something from duck dns…
Look into http traffic! Some servers add something into response and it' accepted by web browser but not by garmin proxy.
makeImageRequest only accepts response that contains only bytes from image…
It depends on how big your app is, and if you are doing this in a background service, how big that is. And when you get the image on the device, it's been converted to the format used on Garmin devices so might be larger than the original file
As usual try/catch doesn't work as advertised. Based on what I see and don't see the out of memory error is in the function that has the makeImageRequest call, but the error is coming from Garmin, not my catch. Thus, the only executable statement IS makeImageRequest. So, why would the request get an out of memory condition before the call back function is started? I've tried smaller and smaller images, now at 40x23 png. Whatever the problem is, it seems like something is triggering a "feature" causing the callback handler to crash.
Memory from getSystemStats()
used 51752
free 75160
total 126912
And in the background from getSystemStats()
Background: used 12104
Background: free 49272
Background: total 61376
Error: Out Of Memory Error
Details: failed inside handle_image_callback
Stack:
Apparently it isn't my code or my server. When I tried it on the simulated CIQ 3 Captain Marvel it worked a few times, meaning 200 and the returned image displayed on the watch face. But sometimes I get a 404 and sometimes it crashes, so obviously something else is going on. It sure would be nice to get meaningful error messages, but that's asking a lot.
With more experimentation I've learned a lot more:
makeWebRequest works every time on the first try. The server log shows a request from my gateway IP address, and PHP says it took 4 ms to find the nearest tide station to my location and return the harmonic constituents for it. For the RESTful URL fields, the zeroth is the API, first is the PHP script, and second is the device unique identifier + System.gettimer() + retry counter. For now this field is just for debugging. You can see that the retry counter is zero. For this type of request the third and fourth fields are my latitude and longitude in radians. The agent says it is Mozilla/5.0 (important later):
Tide station request from makeWebRequest: 66.72.221.161 - 2024-01-19T12:49:15+00:00 3135 1 GET /g1/hc/ffa0f28f1a9e91d2133a05fc4ff987c817fb2ab4_34240937_0/+0.533639306/-1.521642584 HTTP/1.1 . 200 1961 - Mozilla/5.0 0.004
makeImageRequest works almost never. I increased the retry count to 100, but it rarely even makes it to 20. For every call to makeImageRequest that returns a 404, the server log shows nothing. Eventually, something will show up in the server log. I have encoded the retry number in to the request URL. I'm not using that REST field, it's for debugging:
Tide station request from makeWebRequest: 66.72.221.161 - 2024-01-19T12:49:15+00:00 3135 1 GET /g1/hc/ffa0f28f1a9e91d2133a05fc4ff987c817fb2ab4_34240937_0/+0.533639306/-1.521642584 HTTP/1.1 . 200 1961 - Mozilla/5.0 0.004 Image file request from makeImageRequest: 198.233.176.132 - 2024-01-19T15:24:18+00:00 3300 1 GET /g1/ci/ffa0f28f1a9e91d2133a05fc4ff987c817fb2ab4_43543718_10/test.png HTTP/1.1 . 200 5491 - Java/11.0.20 0.001 198.233.176.132 - 2024-01-19T15:24:18+00:00 3300 2 GET /g1/ci/ffa0f28f1a9e91d2133a05fc4ff987c817fb2ab4_43543718_10/test.png HTTP/1.1 . 200 5497 - Java/11.0.20 0.001
In this sample the retry counter was at 10. The client IP for makeImageRequest is registered to CenturyLink, that's all whois knows. The request URL was received twice in a row, from agent Java/11.0.20. After this I get an uncatachable error:
Error: Out Of Memory Error Details: failed inside handle_image_callback Stack:
I have seen it work twice, so I know the monkey C I have in the simulator and the PHP on the server are not the issue.
At this point I tried wireshark on the PC, and what I learned is that a request from the simulator is going to 104.16.73.50 and it identifies itself as services.garmin.com EVERY time makeImageRequest is called, but it's being dropped for some reason, and when it does forward the request it's most likely to cause a crash:
No. Time Source Destination Protocol Length Info (previous tries omitted) My server didn't see this (retry 16) 12092 814.985750 192.168.3.144 104.16.173.50 TCP 66 49943 → 443 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM 12094 815.022995 192.168.3.144 104.16.173.50 TCP 54 49943 → 443 [ACK] Seq=1 Ack=1 Win=263168 Len=0 12095 815.024861 192.168.3.144 104.16.173.50 TLSv1.2 235 Client Hello (SNI=services.garmin.com) 12099 815.070499 192.168.3.144 104.16.173.50 TCP 54 49943 → 443 [ACK] Seq=182 Ack=2528 Win=263168 Len=0 12100 815.073234 192.168.3.144 104.16.173.50 TLSv1.2 147 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message 12102 815.112765 192.168.3.144 104.16.173.50 TLSv1.2 367 Application Data 12107 815.263626 192.168.3.144 104.16.173.50 TCP 54 49943 → 443 [ACK] Seq=588 Ack=4607 Win=263168 Len=0 12108 815.264601 192.168.3.144 104.16.173.50 TLSv1.2 85 Encrypted Alert 12109 815.265033 192.168.3.144 104.16.173.50 TCP 54 49943 → 443 [FIN, ACK] Seq=619 Ack=4607 Win=263168 Len=0 12110 815.276657 192.168.3.144 104.16.9.45 TLSv1.2 576 Application Data 12113 815.301001 192.168.3.144 104.16.173.50 TCP 54 49943 → 443 [ACK] Seq=620 Ack=4608 Win=263168 Len=0 12118 815.508469 192.168.3.144 104.16.9.45 TCP 54 49927 → 443 [ACK] Seq=9060 Ack=25633 Win=263168 Len=0 My server didn't see this (retry 17) 12119 815.615881 192.168.3.144 104.16.173.50 TCP 66 49944 → 443 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM 12121 815.649402 192.168.3.144 104.16.173.50 TCP 54 49944 → 443 [ACK] Seq=1 Ack=1 Win=263168 Len=0 12122 815.650475 192.168.3.144 104.16.173.50 TLSv1.2 235 Client Hello (SNI=services.garmin.com) 12126 815.693650 192.168.3.144 104.16.173.50 TCP 54 49944 → 443 [ACK] Seq=182 Ack=2528 Win=263168 Len=0 12127 815.699507 192.168.3.144 104.16.173.50 TLSv1.2 147 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message 12129 815.743076 192.168.3.144 104.16.173.50 TLSv1.2 367 Application Data 12134 815.882957 192.168.3.144 104.16.173.50 TCP 54 49944 → 443 [ACK] Seq=588 Ack=4615 Win=263168 Len=0 12135 815.883922 192.168.3.144 104.16.173.50 TLSv1.2 85 Encrypted Alert 12136 815.884220 192.168.3.144 104.16.173.50 TCP 54 49944 → 443 [FIN, ACK] Seq=619 Ack=4615 Win=263168 Len=0 12137 815.891028 192.168.3.144 104.16.9.45 TLSv1.2 576 Application Data 12140 815.921807 192.168.3.144 104.16.173.50 TCP 54 49944 → 443 [ACK] Seq=620 Ack=4616 Win=263168 Len=0 12156 816.109998 192.168.3.144 104.16.9.45 TCP 54 49927 → 443 [ACK] Seq=9582 Ack=26946 Win=261632 Len=0 My server received this (retry 18), then the app crashed: 12157 816.233784 192.168.3.144 104.16.173.50 TCP 66 49945 → 443 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM 12159 816.273257 192.168.3.144 104.16.173.50 TCP 54 49945 → 443 [ACK] Seq=1 Ack=1 Win=263168 Len=0 12160 816.274521 192.168.3.144 104.16.173.50 TLSv1.2 235 Client Hello (SNI=services.garmin.com) 12164 816.319658 192.168.3.144 104.16.173.50 TCP 54 49945 → 443 [ACK] Seq=182 Ack=2530 Win=263168 Len=0 12165 816.322198 192.168.3.144 104.16.173.50 TLSv1.2 147 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message 12171 816.361248 192.168.3.144 104.16.173.50 TLSv1.2 367 Application Data 12177 816.509596 192.168.3.144 104.16.173.50 TCP 54 49945 → 443 [ACK] Seq=588 Ack=4615 Win=263168 Len=0 12178 816.510732 192.168.3.144 104.16.173.50 TLSv1.2 85 Encrypted Alert 12179 816.511325 192.168.3.144 104.16.173.50 TCP 54 49945 → 443 [FIN, ACK] Seq=619 Ack=4615 Win=263168 Len=0 12180 816.519235 192.168.3.144 104.16.9.45 TLSv1.2 576 Application Data 12183 816.550910 192.168.3.144 104.16.173.50 TCP 54 49945 → 443 [ACK] Seq=620 Ack=4616 Win=263168 Len=0 12192 817.034691 192.168.3.144 104.16.9.45 TCP 54 49927 → 443 [ACK] Seq=10104 Ack=29742 Win=263168 Len=0 12195 817.035042 192.168.3.144 104.16.9.45 TCP 54 49927 → 443 [ACK] Seq=10104 Ack=32538 Win=263168 Len=0 12198 817.089590 192.168.3.144 104.16.9.45 TCP 54 49927 → 443 [ACK] Seq=10104 Ack=33408 Win=262144 Len=0 12863 918.879825 192.168.3.144 104.18.71.229 TCP 54 49924 → 80 [ACK] Seq=947 Ack=1092 Win=261888 Len=0 12868 919.214467 192.168.3.144 104.18.71.229 TCP 54 49925 → 443 [ACK] Seq=1246 Ack=4402 Win=263168 Len=0 14929 1217.036987 192.168.3.144 104.16.9.45 TCP 54 49927 → 443 [ACK] Seq=10104 Ack=33440 Win=262144 Len=0
What I've learned is that we're relying on some server, presumably Garmin's, to do some image processing and fulfill the request. That is to say, this is an unsolvable problem, and attempts to debug code and our servers are in vain.
Now with SDK 7 I see that the image request hits my server on the first try, and the result code in the nginx server log is 200. However, I now get this error in the debug console:
Error: Exception occurred
Details: failed inside handle_image_callback
Exception: Class usage is not allowed for the current app type.
The web request in the same background class still works fine, so it doesn't seem like it's the background part it doesn't like. I get this println in the output:
System.println("requestCenterImage getURL " + v_getURL);
Communications.makeImageRequest(v_getURL, null, _cPic, method(:onReceiveCenterImage));
But not the println that is the first line of the receive method:
public function onReceiveCenterImage(response as Number, data as imgData) as Void {
System.println("onReceiveCenterImage response " + response + ", getTimer " + System.getTimer());
So the problem seems to be in makeImageRequest itself.
what is your app type, and device?
Fenix 7X watch face with CIQ 5.0.0 goodness in the watch and the simulator. With SDK 6.4.2 I mostly I get this, but I did see it work one or twice so at least it is or was theoretically possible.
Error: Out Of Memory Error
Details: failed inside handle_image_callback
Stack:
The image size according to nginx is 2317 bytes, and the request is asking for it to be sized to 20x20 so it shouldn't be an actual bytes issue.
Well, it works when I try it with the Captain Marvel simulator, so apparently the nginx server config and monkey c code are all OK. It's the Fenix 7X sim.
Some CIQ 3 devices work, like Venu Sq. Music Edition and vivoactive 4, some don't. I get this on the Fenix 5S sim:
Error: Symbol Not Found Error
Details: Could not find symbol 'BitmapReference'
Stack:
- setBitmap() at D:\grmn\prj\di\connectiq\toolchain\mbsimulator\submodules\technology\monkeybrains\virtual-machine\api\WatchUi.mb:4440 0x30003bca
- initialize() at D:\grmn\prj\di\connectiq\toolchain\mbsimulator\submodules\technology\monkeybrains\virtual-machine\api\WatchUi.mb:4373 0x300039ac
- loadPic() at C:\Users\Andy\Desktop\Garmin-GIT\Annulus\source\AnnulusFace.mc:772 0x10002e3d
- onBackgroundData() at C:\Users\Andy\Desktop\Garmin-GIT\Annulus\source\AnnulusApp.mc:107 0x100009a8
Executing this statement:
public function loadPic(bMap) {
bMap = new WatchUi.Bitmap((bMap instanceof ResourceId) ? {:rezId=>bMap} : {:bitmap=>bMap}); // SDK 7+
Why is a CIQ 3 device looking for BitmapReference? The docs say it doesn't exist until CIQ 4, hence the error.
I have yet to find one CIQ 4 or 5 device that it doesn't throw an error on; Some have this:
Error: Symbol Not Found Error
Details: Failed invoking <symbol>
Stack:
Some do this:
Error: Exception occurred
Details: failed inside handle_image_callback
Exception: Class usage is not allowed for the current app type.
So close, yet so far...
Are your devices files up to date and are you using the 7.1.1 SDK?
Sound like you are also dealing with the devices with the graphics pool and those that don't