Closed JF002 closed 2 years ago
Since the filename would likely be hardcoded, we could check for corruption by having a BLE characteristic that generates and sends a crc32 (or some other algorithm) back to the companion. This would probably be a lot faster than reading back the whole file and prevent false positives where the read itself was corrupted.
Your proposal seems good. The only problem I foresee is that gzip decompression would have to take place on the watch and I am not sure how expensive that is resource-wise and how long it would take. The .gz
is actually unnecessary. If just .tar
is used alone, there is no compression. There is also the possibility of using a .zip
without compression, but that might just confuse people when they try to modify the assets file and their archiving program generates a compressed zip.
Thanks for your feedback @Arsen6331 :+1: Adding a characteristic, or extending the BLE FS API is indeed a good idea to allow checking data validity with a CRC.
Regarding (de)compression, it would be done by the companion app. I certainly don't want to implement zip/gzip algorithms in InfiniTime. The archive is just a way to pack multiple files into a single one to make the flashing procedure easier for the end user. And yes, you are right, the compression might not be needed and we could just use .tar
for this use-case. I mentioned compression because that's how DFU are currently packaged (using zip
).
Also, the archive (without compression) could possibly be placed into the already existing DFU zip with a new entry for it in the manifest. That will mean there is still just one file for the user to get, rather than two,
Also, the archive (without compression) could possibly be placed into the already existing DFU zip with a new entry for it in the manifest. That will mean there is still just one file for the user to get, rather than two,
That's a good idea! Assuming it won't confuse companion apps, of course :)
That's a good idea! Assuming it won't confuse companion apps, of course :)
It shouldn't, since each file has a name in the manifest, like bin_file
for the binary and dat_file
for the init packet. This could just be asset_file
or something, and companions that don't use it just won't get that key from the map.
We might not need to alter the manifest, and just add the resource file and maybe a metadata json file to the dfu archive.
As long as the name of the asset file always stays the same. The reason I use the manifest is that the names of the .bin and .dat files contain the version, so it's the only way I can know for sure what the filename is.
I did a bit of progress : files (fonts and pictures) are now converted and packed into a single .zip file using a CMake custom_target
. This target
src/displayapp/fonts/generate.py
)generate.py
above)infinitime-resources-1.11.0.zip
The content of the zip file looks like this:
infinitime-resources-1.11.0.zip
|
|---- 7segments_40.bin
|---- 7segments_115.bin
|---- infineat-1bin
...
|---- resources.json
resources.json:
{
"resources": [
{
"filename": "7segments_40.bin",
"path": "/7segments_40.bin"
},
{
"filename": "7segments_115.bin",
"path": "/7segments_115.bin"
},i
{
"filename": "infineat-1.bin",
"path": "/infineat-1.bin"
}
],
"obsolete_files": [
{
"path": "/background_v1.bin",
"since": "1.11.0"
},
{
"path": "/font_v2.bin",
"since": "1.11.0"
}
]
}
resources
contains the list of files from the .zip file that must be uploaded to the watch. It contains the name of the file in the .zip file and the path (filename) where it must be written to the watch.obsolete_files
contains a list of files that can optionally remove from the watch. This is a hint to the companion app which lists the files that are not used anymore in this version of infinitime and that can be removed. It's up to the companion app to remove them to free some memory space. Each item contain the filename in the watch FS and the version of infinitime that made that file obsolete.Any feedback regarding this packaging strategy?
EDIT : here is an example package: infinitime-resources-1.10.0.zip
And this is the expected result once the files are uploaded (screenshots using ITD:
./itctl fs ls
d 0.0 B .
d 0.0 B ..
- 4.9 kB 7segments_115.bin
- 760 B 7segments_40.bin
- 4.4 kB bebas.bin
- 1.4 kB infineat-1.bin
- 1.8 kB lv_font_dots_40.bin
- 115 kB matrix.bin
- 40 B settings.dat
- 440 B teko.bin
To support this, companion apps will have to implement our BLE FS API.
I'm wondering how changed assets should be handled. If someone decides to upload a font that is different from the one in the update, how would the companion know not to override it? I am thinking that maybe there should be a file full of crc32s for each asset, and then when the companion is doing the update, it leaves the files that have changed since that crc was taken?
I have also been thinking about this. Here's what we could do:
something_v1.bin
for example.something_v2.bin' and add
something_v1.bin' to the list of obsolete files.This seems quite simple, allows to easily upgrade/downgrade the resources, and hints the companion app which older files can be removed.
Using filename instead of CRC to detect changes in files will probably be faster (and easier as there's no support for CRC in the FS right now).
No, I mean what if the user wants to modify a resource? Like if an app uses an image of some sort and the user wants to use a custom image instead.
Mhm that's a use-case I haven't anticipated... But I have the feeling that this should be handled on the companion app side. It could manage a list of "locked" files that cannot be overwritten, for example. Or yes, maintain a list of file that were overwritten manually by the user and not automatically update them when updating the whole resource package.
It probably should be handled by companions, but I think it should be standardized, because some users will use Gadgetbridge to update once, and then ITD the next time, and if ITD uses a different mechanism than Gadgetbridge, it'll just overwrite all their changes.
That won't be easy.. even if companion app developers agree on a single mechanism, you'll have to sync them across all your devices... Unless this "do not overwrite this file" flag is stored in the watch itself?
Yeah, that's what I was thinking. Maybe a file on the watch that looks like this
764df7d2 a.bin
b3e0e55f b.bin
...
And then add a characteristic or change to the FS that allows you to get a crc from the watch. It's the only way I can think of, because if it's stored on the companion device, that will mean, as you said, users would have to sync the file, and make sure it never gets deleted if they, for example, reinstall their OS.
Good idea! However, I might work on this on a second step, as I would like to implement a working version of the support for "external resources" soon. This feature could probably be added in a second step.
maybe we could ignore this on the companion side and let the companion install everything which is referenced.
On the InfiniTime side we could have default-images used by the firmware and another set of user-provide-able overrides. For example we have a default background image for the clock, but if a user installs a user-bg.bin
InfiniTime loads this instead of the default image
That works, but we have to consider that it will take up a lot more space
I've just added an example package and the expected results (via ITD) in the original comment.
Here is the corresponding PR : https://github.com/InfiniTimeOrg/InfiniTime/pull/1299
Ok, I have a working implementation of this in my infinitime
package now. Next step is to integrate that into ITD, which shouldn't be difficult if I do it before performing DFU.
The new branch of ITD with resource loading is now complete: https://gitea.arsenm.dev/Arsen6331/itd/src/branch/resource-loading.
It currently does not do it as part of the DFU as I am not sure yet whether to do it before or after, and I don't know how this resources zip will be distributed (separate file, inside the dfu zip, etc.). Instead, there is now an itctl res load <zip>
command.
Thanks @Arsen6331 for integrating this in ITD! On my side, I'm testing the procedure in Amazfish. Here are 2 videos :
https://user-images.githubusercontent.com/2261652/188277370-ea6f0280-fa48-43c7-80d2-be7c621668bc.mp4
https://user-images.githubusercontent.com/2261652/188277385-ed7fe88e-cbad-4758-954e-7c37c26d7350.mp4
And everything seems to work well in both case ;)
Hi all, I'm try to do this PR in my side, but I have problems with cmd : ./idctl fs ls or command related to fs, it returns error : "Operation is not supported"
cuong@cuongPC:~/itd$ ./itd 3:53PM INF Connected to InfiniTime version=1.10.0 3:53PM INF Initialized InfiniTime music controls 3:53PM INF Relaying calls to InfiniTime 3:53PM INF Relaying notifications to InfiniTime 3:53PM INF Started control socket path=/tmp/itd/socket
cuong@cuongPC:~/itd$ ./itctl fs ls 4:06PM FTL Error while running app error="Operation is not supported"
I use other command normally, I can get heart rate, motion, steps ..., and the Watch can receive date, time, alarm .... Just only BLE Filesystem can't work for me.
Can you help me about it ?? Thanks
I don't think the resource feature has already been merged into the master branch of ITD. Have you tried the 'resource-loading' branch?
"Operation is not supported" is an error coming from BlueZ (specifically org.bluez.Error.NotSupported
). It usually means either your BlueZ or your Bluetooth adapter doesn't support something ITD is trying to do.
Hi @JF002 I have tried the 'resource-loading' branch but still having problems. Hi @Arsen6331 I have read this topic found that I had the same problem with ITCactus and detailed his problems here So I think cli for FS (e.g. "itctl fs ls") doesn't work with some PC or Laptop and I can't find useful info about this issues. I will check some ways to resolve this problems or find alternative app to test this feature. Thanks all.
@tucuongbrt Any update about your issue? Have you tried with amazfish which already implements this feature?
@JF002 I have fixed my issue. In my computer, I use BlueZ version 5.53 and it dosen't support battery UUID and FS UUID. So I have updated the latest BlueZ version (5.65) and it works normally. Currently, I use ITD and InfinitimeExplorer for uploading resources.
@tucuongbrt Glad to read that your issue is fixed. I didn't know the version of Bluez could have an impact on which UUIDs are supported...
@tucuongbrt Glad to read that your issue is fixed. I didn't know the version of Bluez could have an impact on which UUIDs are supported...
Actually, it would most likely be the DBus interface rather than the UUIDs. If I had to guess, I'd say it was the fact that ITD requests the MTU when transferring files. BlueZ only recently added the ability to request the MTU, so older BlueZ versions wouldn't support it.
@JF002 is the actual build (that is about 400kb) have his ressource removed? more over , i don't see a ressource zip generated in ci ? so how and what to flash in order to have the last infinitme? since , infinineat have been merged , i would like to try use infinneat (and maybe the new watchface ) thanks
@lman0 The builds on github do not contain the resources yet. I still have to add that functionality to the workflow. I'll post more info about this when it's done ;)
@lman0 I've just updated the build workflow. Here's how to use it:
REMINDER : this functionality is not released yet, and is still considered experimental!
thank @JF002 for adding the workflows ! , it's helpful so i/people can help test it!
by the way , you should add that https://github.com/joaquimorg/InfinitimeExplorer , and his webapp https://infinitimeexplorer.netlify.app/ seem be able to upload as well this resource file , for thos that have an android phone (or iphone ?) that a life save !
also , did you displaced the fonts , that were/are inside the firmware in the new resource file ? i remember you said , you can't add app because there no space left in firmware for doing so . because of space taken by the fonts of other watchface s and apps. and the firmware was at that time at 400k .
with the newest version of InfiniSim
(after https://github.com/InfiniTimeOrg/InfiniSim/pull/70 got merged) the resource.zip
is created in the InfiniSim
project. You still need to install lv_img_conv
just like done in InfiniTime
. But you don't have to build the firmware just to play with resource.zip
file creation ;)
I close this issue as it was implemented in https://github.com/InfiniTimeOrg/InfiniTime/pull/1299
Verification
Pitch us your idea!
Let's specify how resources will be packaged and handled by companion apps
Description
In #321 I did a lot of experiments with the external flash storage and the file system. The goal is to use this external flash memory to store big resources (pictures and fonts) so that we can free quite a lot of space in the internal flash memory.
In this comment, I listed the action points that must be done before we can release this feature. This discussion is about the resources packaging and management by companion app : how will we packaged the resource files so companion app can upload them to the watch using the BLE FS API ?
Please note that this is a technical discussion mostly targeted to InfiniTime and companion apps developers.
During my experiments, I used ITD to manually upload previously generated binary files to the watch. I sometimes needed to retry because the transfer would fail for some reason. I also had no way to check if the data were corrupted during the transfer. The upload of a full picture (24024016b = 115200B) took ~2 minutes, iirc.
Sending random binary files to the watch does not fit well with the end-users. I would like all the file to be automatically generated at build time (this is not the scope of this discussion), packaged into a single file with all the info needed for companion app to automatically upload the files to the watch.
Here's my proposal :
Questions:
So... this is a request for comment. Will this simple packaging strategy work well with InfiniTime and companion app to upload fonts and pictures in the external flash storage?