1111#include "utils/util.h"
1212
1313#include <cbor.h>
14- #include <cdecoder .h>
15- #include <cencoder .h>
14+ #include <ur_decoder .h>
15+ #include <ur_encoder .h>
1616
1717// PSBT serialisation functions
1818bool deserialise_psbt (const uint8_t * bytes , size_t bytes_len , struct wally_psbt * * psbt_out );
@@ -181,25 +181,23 @@ bool bcur_parse_bip39_wrapper(
181181
182182 // Decode bcur string
183183 bool ret = false;
184- uint8_t decoder [ URDECODER_SIZE ] ;
185- urcreate_placement_decoder (decoder , sizeof ( decoder ) );
186- if (!urreceive_part_decoder (decoder , bcur ) || !uris_success_decoder (decoder )) {
184+ ur_decoder_t * const decoder = ur_decoder_new () ;
185+ JADE_ASSERT (decoder );
186+ if (!ur_decoder_receive_part (decoder , bcur ) || !ur_decoder_is_success (decoder )) {
187187 JADE_LOGW ("Unable to decode bcur bip39 string from single part" );
188188 goto cleanup ;
189189 }
190190
191- // Read the result
192- char const * type = NULL ;
193- uint8_t * result = NULL ;
194- size_t result_len = 0 ;
195- urresult_ur_decoder (decoder , & result , & result_len , & type );
196- if (!type || !result || !result_len || strcasecmp (BCUR_TYPE_CRYPTO_BIP39 , type )) {
191+ // Read the result - borrowed from the decoder, freed with it
192+ const ur_result_t * const result = ur_decoder_get_result (decoder );
193+ if (!result || !result -> type || !result -> cbor_data || !result -> cbor_len
194+ || strcasecmp (BCUR_TYPE_CRYPTO_BIP39 , result -> type )) {
197195 JADE_LOGW ("Unable to decode bcur bip39 string to expected type %s" , BCUR_TYPE_CRYPTO_BIP39 );
198196 goto cleanup ;
199197 }
200198
201199 // Decode the cbor
202- if (!bcur_parse_bip39 (result , result_len , mnemonic , mnemonic_len , written )) {
200+ if (!bcur_parse_bip39 (result -> cbor_data , result -> cbor_len , mnemonic , mnemonic_len , written )) {
203201 JADE_LOGW ("Failed to parse bcur bip39 cbor message" );
204202 goto cleanup ;
205203 }
@@ -208,7 +206,7 @@ bool bcur_parse_bip39_wrapper(
208206 ret = true;
209207
210208cleanup :
211- urfree_placement_decoder (decoder );
209+ ur_decoder_free (decoder );
212210 return ret ;
213211}
214212
@@ -626,22 +624,24 @@ static bool collect_any_bcur(qr_data_t* qr_data)
626624
627625 // The scanned data looks like a bcur code or fragment, add it to the bcur decoder
628626 // and return true only when the bcur decoder says the message is complete.
629- const bool processed_part = urreceive_part_decoder (qr_data -> ctx , (const char * )qr_data -> data );
627+ const bool processed_part = ur_decoder_receive_part (qr_data -> ctx , (const char * )qr_data -> data );
630628
631- // On hard failure, reset the decoder
632- if (uris_failure_decoder (qr_data -> ctx )) {
629+ // On hard failure (complete but unsuccessful - eg. checksum mismatch), reset the decoder
630+ // NOTE: the caller must fetch the decoder back from qr_data->ctx as it may be replaced here
631+ if (ur_decoder_is_complete (qr_data -> ctx ) && !ur_decoder_is_success (qr_data -> ctx )) {
633632 JADE_LOGE ("Failure to scan bcur data - resetting the decoder" );
634- urfree_placement_decoder (qr_data -> ctx );
635- urcreate_placement_decoder (qr_data -> ctx , URDECODER_SIZE );
633+ ur_decoder_free (qr_data -> ctx );
634+ qr_data -> ctx = ur_decoder_new ();
635+ JADE_ASSERT (qr_data -> ctx );
636636 return false;
637637 }
638638
639639 // Update associated progress bar - be a bit defensive here
640- const bool decoded = uris_success_decoder (qr_data -> ctx );
641- const size_t nreceived = urreceived_parts_count_decoder (qr_data -> ctx );
640+ const bool decoded = ur_decoder_is_success (qr_data -> ctx );
641+ const size_t nreceived = ur_decoder_received_parts_count (qr_data -> ctx );
642642 if (processed_part && nreceived ) {
643643 // NOTE: can only call 'expected' once we have received at least one part
644- const size_t nexpected = urexpected_part_count_decoder (qr_data -> ctx );
644+ const size_t nexpected = ur_decoder_expected_part_count (qr_data -> ctx );
645645
646646 // If fully decoded show full bar - but if not fully decoded
647647 // don't show a full bar - pause at 'almost done' if required.
@@ -666,34 +666,37 @@ bool bcur_scan_qr(const char* prompt_text, char** output_type, uint8_t** output,
666666 JADE_INIT_OUT_PPTR (output );
667667 JADE_INIT_OUT_SIZE (output_len );
668668
669- uint8_t urdecoder [ URDECODER_SIZE ] ;
670- urcreate_placement_decoder (urdecoder , sizeof ( urdecoder ) );
669+ ur_decoder_t * urdecoder = ur_decoder_new () ;
670+ JADE_ASSERT (urdecoder );
671671 progress_bar_t progress_bar = {};
672672 qr_data_t qr_data = { .len = 0 , .is_valid = collect_any_bcur , .ctx = urdecoder , .progress_bar = & progress_bar };
673673
674674 // Scan qr code using the bcur decoder to collate multiple frames if required
675- if (!jade_camera_scan_qr (& qr_data , prompt_text , QR_GUIDE_SHOW , help_url )) {
675+ // NOTE: collect_any_bcur() may replace the decoder (on hard failure), so
676+ // refresh the local pointer from qr_data.ctx once scanning ends.
677+ const bool scanned = jade_camera_scan_qr (& qr_data , prompt_text , QR_GUIDE_SHOW , help_url );
678+ urdecoder = qr_data .ctx ;
679+ if (!scanned ) {
676680 // User exited without completing scanning
677- urfree_placement_decoder (urdecoder );
681+ ur_decoder_free (urdecoder );
678682 return false;
679683 }
680684
681685 // Copy output into output params - caller takes ownership
682- if (uris_success_decoder (urdecoder )) {
686+ if (ur_decoder_is_success (urdecoder )) {
683687 // bcur message scanned - extract from decoder and return the payload
684- uint8_t * result = NULL ;
685- size_t result_len = 0 ;
686- const char * result_type = NULL ;
687- urresult_ur_decoder (urdecoder , & result , & result_len , & result_type );
688+ // NOTE: the result is borrowed from the decoder, and freed with it
689+ const ur_result_t * const result = ur_decoder_get_result (urdecoder );
688690 JADE_ASSERT (result );
689- JADE_ASSERT (result_len );
690- JADE_ASSERT (result_type );
691+ JADE_ASSERT (result -> cbor_data );
692+ JADE_ASSERT (result -> cbor_len );
693+ JADE_ASSERT (result -> type );
691694
692695 // Copy payload and bc-ur type
693- * output = JADE_MALLOC_PREFER_SPIRAM (result_len + offset );
694- memcpy (* output + offset , result , result_len );
695- * output_len = result_len + offset ;
696- * output_type = strdup (result_type );
696+ * output = JADE_MALLOC_PREFER_SPIRAM (result -> cbor_len + offset );
697+ memcpy (* output + offset , result -> cbor_data , result -> cbor_len );
698+ * output_len = result -> cbor_len + offset ;
699+ * output_type = strdup (result -> type );
697700 } else {
698701 // Not a bc-ur code - copy straight payload and append a nul-terminator.
699702 // Leave bc-ur type as NULL to indicate data was not a bc-ur payload.
@@ -705,7 +708,7 @@ bool bcur_scan_qr(const char* prompt_text, char** output_type, uint8_t** output,
705708 }
706709
707710 // Free the decoder and return true (as we scanned data successfully)
708- urfree_placement_decoder (urdecoder );
711+ ur_decoder_free (urdecoder );
709712 return true;
710713}
711714
@@ -741,9 +744,9 @@ void bcur_create_qr_icons(const uint8_t* payload, const size_t len, const char*
741744 JADE_LOGI ("BC-UR encoding payload length %u as type %s" , len , bcur_type );
742745 JADE_LOGI ("Targetting qr-code version %u, capacity %u (alphanumeric mode), using max fragment size %u" , qr_version ,
743746 qrcode_alphanumeric_capacity , bcur_max_fragment_size );
744- uint8_t encoder [ URENCODER_SIZE ] ;
745- urcreate_placement_encoder (encoder , sizeof ( encoder ), bcur_type , payload , len , bcur_max_fragment_size , 0 , 8 );
746- const size_t min_num_fragments = urseqlen_encoder (encoder ); // the number of 'pure' data fragments
747+ ur_encoder_t * const encoder = ur_encoder_new ( bcur_type , payload , len , bcur_max_fragment_size , 0 , 8 ) ;
748+ JADE_ASSERT (encoder );
749+ const size_t min_num_fragments = ur_encoder_seq_len (encoder ); // the number of 'pure' data fragments
747750 const size_t num_fragments = BCUR_NUM_FRAGMENTS (min_num_fragments ); // add some fountain-code fragments
748751 JADE_ASSERT (num_fragments >= min_num_fragments );
749752 JADE_LOGI ("Encoded payload length %u as %u pure fragments and %u fountain-code fragments" , len , min_num_fragments ,
@@ -753,11 +756,12 @@ void bcur_create_qr_icons(const uint8_t* payload, const size_t len, const char*
753756 uint8_t * qrbuffer = JADE_MALLOC (qrcode_getBufferSize (qr_version ));
754757
755758 // Convert to 'num_fragments' qr-code icons
756- const bool force_uppercase = true; // fetch bcur fragment as uppercase to conform to 'alphanumeric' qr mode
759+ // NOTE: fragments are uppercase, to conform to 'alphanumeric' qr mode
757760 Icon * const qr_icons = JADE_MALLOC (num_fragments * sizeof (Icon ));
758761 for (int ifrag = 0 ; ifrag < num_fragments ; ++ ifrag ) {
759762 char * fragment = NULL ;
760- urnext_part_encoder (encoder , force_uppercase , & fragment );
763+ const bool have_part = ur_encoder_next_part (encoder , & fragment );
764+ JADE_ASSERT (have_part );
761765 const size_t fragment_len = strlen (fragment );
762766 JADE_LOGI ("Fragment %u, making qr-code icon with data (length: %u): %s" , ifrag , fragment_len , fragment );
763767
@@ -768,15 +772,15 @@ void bcur_create_qr_icons(const uint8_t* payload, const size_t len, const char*
768772 QRCode qrcode ;
769773 const int qret = qrcode_initText (& qrcode , qrbuffer , qr_version , BCUR_QR_ECC , fragment );
770774 JADE_ASSERT (qret == 0 );
771- urfree_encoded_encoder (fragment );
775+ free (fragment );
772776
773777 // Convert fragment to Icon
774778 qrcode_toIcon (& qrcode , qr_icons + ifrag , QR_SCALE_FACTOR [qr_version ]);
775779 }
776- JADE_ASSERT (uris_complete_encoder (encoder ));
780+ JADE_ASSERT (ur_encoder_is_complete (encoder ));
777781
778782 free (qrbuffer );
779- urfree_placement_encoder (encoder );
783+ ur_encoder_free (encoder );
780784
781785 // Return the created icons
782786 * icons = qr_icons ;
@@ -810,11 +814,11 @@ bool bcur_check_fragment_sizes(void)
810814 size_t max = 0 ;
811815
812816 for (size_t len = maxlen - 8 ; len < sizeof (payload ); ++ len ) {
813- uint8_t encoder [ URENCODER_SIZE ] ;
814- urcreate_placement_encoder (encoder , sizeof ( encoder ), type , payload , len , maxlen , 0 , 8 );
817+ ur_encoder_t * const encoder = ur_encoder_new ( type , payload , len , maxlen , 0 , 8 ) ;
818+ JADE_ASSERT (encoder );
815819
816820 char * fragment = NULL ;
817- urnext_part_encoder (encoder , true , & fragment );
821+ ur_encoder_next_part (encoder , & fragment );
818822 JADE_ASSERT (fragment );
819823 const size_t fraglen = strlen (fragment );
820824 if (fraglen + 4 > capacity ) {
@@ -827,8 +831,8 @@ bool bcur_check_fragment_sizes(void)
827831 if (fraglen > max ) {
828832 max = fraglen ;
829833 }
830- urfree_encoded_encoder (fragment );
831- urfree_placement_encoder (encoder );
834+ free (fragment );
835+ ur_encoder_free (encoder );
832836 }
833837 JADE_LOGI ("max: %u (of target/limit %u)" , max , capacity );
834838 }
0 commit comments