diff --git a/matrix_qrcode/src/utils.rs b/matrix_qrcode/src/utils.rs index 6a30ff76..faff2f71 100644 --- a/matrix_qrcode/src/utils.rs +++ b/matrix_qrcode/src/utils.rs @@ -17,7 +17,7 @@ use std::convert::TryInto; use base64::{decode_config, encode_config, STANDARD_NO_PAD}; #[cfg(feature = "decode_image")] use image::{ImageBuffer, Luma}; -use qrcode::QrCode; +use qrcode::{bits::Bits, EcLevel, QrCode, Version}; #[cfg(feature = "decode_image")] use crate::error::DecodingError; @@ -73,7 +73,21 @@ pub(crate) fn to_qr_code( shared_secret: &str, ) -> Result { let data = to_bytes(mode, flow_id, first_key, second_key, shared_secret)?; - Ok(QrCode::new(data)?) + + // Mobile clients seem to have trouble decoding the QR code that gets + // generated by `QrCode::new()` it seems to add a couple of data segments + // with different data modes/types. The parsers seem to assume a single + // data type and since we start with an ASCII `MATRIX` header the rest of + // the data gets treated as a string as well. + // + // We make sure that there isn't an ECI bit set and we just push the bytes, + // this seems to help since the decoder doesn't assume an encoding and + // treats everything as raw bytes. + let mut bits = Bits::new(Version::Normal(7)); + bits.push_byte_data(&data)?; + bits.push_terminator(EcLevel::L)?; + + Ok(QrCode::with_bits(bits, EcLevel::L)?) } #[cfg(feature = "decode_image")]