Skip to content

usb: enforce LE bytes for descriptor strings #98

@kammce

Description

@kammce

Currently, we are using u16string_view which is problematic because the endianness of this type isn't LE but native. We need it to be LE for USB to understand it correctly. This may mean that we need our own fixed sized string container that automatically converts string (constants or otherwise) into LE bytes.

template<std::size_t N>
struct usb_string {
    std::array<char16_t, N> data;
    
    consteval usb_string(char16_t const (&p_str)[N]) {
        for (std::size_t i = 0; i < N; ++i) {
            if constexpr (std::endian::native == std::endian::little) {
                data[i] = p_str[i];
            } else {
                // Byte-swap to LE
                data[i] = (p_str[i] >> 8) | (p_str[i] << 8);
            }
        }
    }
    
    constexpr std::span<char16_t const> view() const {
        return std::span(data).first(N - 1); // exclude null terminator
    }

    constexpr operator std::span<char16_t const>() const {
        return view();
    }
};

Something like the above:

static constexpr auto manufacturer = usb_string(u"ACME Corp");

// In descriptor:
.p_manufacturer = manufacturer.view(),

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions