Skip to content

hotfix - miximum 50 files for each syncing time#7163

Open
TuEmb wants to merge 3 commits intoBasedHardware:mainfrom
TuEmb:TuEmb/fix_max_mtu_issue
Open

hotfix - miximum 50 files for each syncing time#7163
TuEmb wants to merge 3 commits intoBasedHardware:mainfrom
TuEmb:TuEmb/fix_max_mtu_issue

Conversation

@TuEmb
Copy link
Copy Markdown
Contributor

@TuEmb TuEmb commented May 4, 2026

The device is not able to send file list when total file list is over 61 files ( > maximum MTU size - 498):

image

For each sync cycle, the device sends up to the 50 oldest files. If the app receives exactly 50 files, it will request more after the sync completes. If fewer than 50 files are received, no further requests

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 4, 2026

Greptile Summary

This PR fixes an MTU overflow bug in send_file_list_response by capping the number of files sent per sync cycle to 50 (≤ 401 bytes, safely under the observed ~498-byte MTU). It also adds a dynamic max_files_by_payload guard derived from the runtime-negotiated MTU.

  • P1: The max_files_by_payload secondary cap can silently send fewer than 50 files even when 50+ remain on-device. Because the app's "request more" trigger is received_count == 50, any MTU below ~404 bytes causes the app to stop paginating early and leaves files stranded indefinitely on the device.

Confidence Score: 3/5

Not safe to merge as-is; the MTU-based secondary cap can silently break the pagination contract, causing files to be permanently unsynced on low-MTU links.

One P1 logic bug: max_files_by_payload can truncate the response below the 50-file pagination threshold without the app knowing more files remain. The 50-file hard cap already solves the reported MTU overflow for any link with MTU ≥ 404 bytes, making the secondary cap both redundant in the normal case and harmful in edge cases.

omi/firmware/omi/src/lib/core/storage.c — the max_files_by_payload clamp logic in send_file_list_response

Important Files Changed

Filename Overview
omi/firmware/omi/src/lib/core/storage.c Adds per-response file count cap (50) and dynamic MTU-based payload limit to send_file_list_response; the MTU-based secondary cap can silently truncate below the pagination threshold and leave files stranded on-device.

Sequence Diagram

sequenceDiagram
    participant App
    participant Device as Device (storage.c)

    App->>Device: CMD_LIST_FILES (0x10)
    Device->>Device: refresh_file_list_cache()
    Device->>Device: compute att_payload from bt_gatt_get_mtu()
    Device->>Device: max_files_by_payload = (att_payload-1)/8
    Device->>Device: response_count = MIN(file_count, 50, max_files_by_payload)
    Device-->>App: [count][ts1][sz1]...[tsN][szN]

    alt response_count == 50
        loop for each file in batch
            App->>Device: CMD_READ_FILE [index]
            Device-->>App: file data chunks
            App->>Device: CMD_DELETE_FILE [index]
            Device-->>App: 0x00 ok
        end
        App->>Device: CMD_LIST_FILES (request next batch)
    else response_count < 50
        Note over App: App assumes sync complete — stops requesting
    end
Loading

Reviews (1): Last reviewed commit: "miximum 50 files for each syncing" | Re-trigger Greptile

Comment on lines +284 to +290
int max_files_by_payload = (att_payload > 1U) ? ((att_payload - 1U) / STORAGE_FILE_LIST_ENTRY_SIZE) : 0;
int response_file_count = MIN(sync_file_count, STORAGE_LIST_MAX_FILES_PER_RESPONSE);
response_file_count = MIN(response_file_count, max_files_by_payload);

if (response_file_count < 0) {
response_file_count = 0;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Payload-based cap can silently break pagination protocol

max_files_by_payload is used as a hard upper bound on response_file_count, but the app's "request more" trigger is exactly response_file_count == STORAGE_LIST_MAX_FILES_PER_RESPONSE (50). If the negotiated MTU yields a payload where max_files_by_payload < 50 (any MTU below ~404 bytes, i.e., att_payload < 401), the device will send fewer than 50 entries even when 50+ files exist. The app treats anything less than 50 as "done" and stops requesting, leaving remaining files stranded on the device.

For example: MTU = 350 → att_payload = 347 → max_files_by_payload = (347-1)/8 = 43. With 60 files on disk, response_file_count = min(60, 50, 43) = 43. The app receives 43, concludes syncing is complete, and never retrieves the remaining 17 files.

The 50-file cap alone already guarantees the payload stays within 1 + 50×8 = 401 bytes (plus ATT overhead of 3), fitting any MTU ≥ 404. The max_files_by_payload secondary cap is redundant in the common case and silently breaks pagination in the edge case. Consider removing it, or adding a "more files available" flag so the app can continue paginating regardless of batch size.

Comment on lines +288 to +290
if (response_file_count < 0) {
response_file_count = 0;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Dead-code negative guard

response_file_count is the result of two successive MIN calls where both operands are always non-negative (sync_file_count >= 1 at this point, STORAGE_LIST_MAX_FILES_PER_RESPONSE = 50 > 0, and max_files_by_payload is derived from an unsigned division). The < 0 branch can never be taken.

Suggested change
if (response_file_count < 0) {
response_file_count = 0;
}
/* response_file_count is always >= 0 here; no clamp needed */

@TuEmb TuEmb changed the title fix - miximum 50 files for each syncing time hotfix - miximum 50 files for each syncing time May 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant