diff --git a/lib/subghz/protocols/pocsag.c b/lib/subghz/protocols/pocsag.c index 31a51970a..18a3dd538 100644 --- a/lib/subghz/protocols/pocsag.c +++ b/lib/subghz/protocols/pocsag.c @@ -21,7 +21,6 @@ static const SubGhzBlockConst pocsag_const = { #define POCSAG_CW_MASK 0xFFFFFFFF #define POCSAG_FRAME_SYNC_CODE 0x7CD215D8 #define POCSAG_IDLE_CODE_WORD 0x7A89C197 -#define POCSAG_MAX_MSG 90 struct SubGhzProtocolDecoderPocsag { @@ -33,11 +32,18 @@ struct SubGhzProtocolDecoderPocsag { uint8_t codeword_idx; uint32_t ric; uint8_t func; - FuriString* msg; // partially decoded character uint8_t char_bits; uint8_t char_data; + + // message being decoded + FuriString* msg; + + // Done message, ready to be serialized/deserialized + uint32_t done_ric; + FuriString* done_msg; + }; typedef struct SubGhzProtocolDecoderPocsag SubGhzProtocolDecoderPocsag; @@ -57,6 +63,7 @@ void* subghz_protocol_decoder_pocsag_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_pocsag; instance->generic.protocol_name = instance->base.protocol->name; instance->msg = furi_string_alloc(); + instance->done_msg = furi_string_alloc(); return instance; } @@ -64,6 +71,7 @@ void subghz_protocol_decoder_pocsag_free(void* context) { furi_assert(context); SubGhzProtocolDecoderPocsag* instance = context; furi_string_free(instance->msg); + furi_string_free(instance->done_msg); free(instance); } @@ -78,7 +86,6 @@ void subghz_protocol_decoder_pocsag_reset(void* context) { instance->char_bits = 0; instance->char_data = 0; furi_string_reset(instance->msg); - furi_string_reserve(instance->msg, POCSAG_MAX_MSG); } @@ -100,7 +107,6 @@ static bool pocsag_decode_message_word(SubGhzProtocolDecoderPocsag* instance, ui if (instance->char_bits == 7) { if (instance->char_data == 0) return false; -// FURI_LOG_I(TAG, "%c", instance->char_data); furi_string_push_back(instance->msg, instance->char_data); instance->char_data = 0; instance->char_bits = 0; @@ -112,15 +118,15 @@ static bool pocsag_decode_message_word(SubGhzProtocolDecoderPocsag* instance, ui static void pocsag_message_done(SubGhzProtocolDecoderPocsag* instance) { -// FURI_LOG_I(TAG, "%s", furi_string_get_cstr(instance->msg)); - FURI_LOG_I(TAG, "done: %d", furi_string_size(instance->msg)); - FURI_LOG_I(TAG, "bits: %d", instance->generic.data_count_bit); - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); + furi_string_set(instance->done_msg, instance->msg); + instance->done_ric = instance->ric; + instance->char_bits = 0; instance->char_data = 0; furi_string_reset(instance->msg); - furi_string_reserve(instance->msg, POCSAG_MAX_MSG); + + if(instance->base.callback) + instance->base.callback(&instance->base, instance->base.context); } @@ -136,7 +142,6 @@ void subghz_protocol_decoder_pocsag_feed(void* context, bool level, uint32_t dur if (instance->decoder.decode_count_bit == POCSAG_MIN_SYNC_BITS) { instance->decoder.parser_step = PocsagDecoderStepFoundSync; -// FURI_LOG_I(TAG, "Sync found"); } } else { @@ -164,7 +169,6 @@ void subghz_protocol_decoder_pocsag_feed(void* context, bool level, uint32_t dur switch(instance->decoder.parser_step) { case PocsagDecoderStepFoundSync: if ((instance->decoder.decode_data & POCSAG_CW_MASK) == POCSAG_FRAME_SYNC_CODE) { -// FURI_LOG_I(TAG, "Found preamble!"); instance->decoder.parser_step = PocsagDecoderStepFoundPreamble; instance->decoder.decode_count_bit = 0; instance->decoder.decode_data = 0UL; @@ -176,19 +180,15 @@ void subghz_protocol_decoder_pocsag_feed(void* context, bool level, uint32_t dur codeword = (uint32_t)(instance->decoder.decode_data & POCSAG_CW_MASK); switch (codeword) { case POCSAG_IDLE_CODE_WORD: -// FURI_LOG_I(TAG, "Idle"); instance->codeword_idx++; break; case POCSAG_FRAME_SYNC_CODE: -// FURI_LOG_I(TAG, "Sync"); instance->codeword_idx = 0; break; default: // Here we expect only address messages if (codeword >> 31 == 0) { pocsag_decode_address_word(instance, codeword); -// FURI_LOG_I(TAG, "Address: %" PRIu32 , instance->addr); -// FURI_LOG_I(TAG, "Function: %" PRIu8, instance->func); instance->decoder.parser_step = PocsagDecoderStepMessage; } instance->codeword_idx++; @@ -204,29 +204,21 @@ void subghz_protocol_decoder_pocsag_feed(void* context, bool level, uint32_t dur switch (codeword) { case POCSAG_IDLE_CODE_WORD: // Idle during the message stops the message -// FURI_LOG_I(TAG, "MIdle"); instance->codeword_idx++; instance->decoder.parser_step = PocsagDecoderStepFoundPreamble; pocsag_message_done(instance); -// FURI_LOG_I(TAG, "Msg done %d", instance->msg_len); break; case POCSAG_FRAME_SYNC_CODE: -// FURI_LOG_I(TAG, "MSync"); instance->codeword_idx = 0; break; default: // In this state, both address and message words can arrive if (codeword >> 31 == 0) { -// FURI_LOG_I(TAG, "MAddr"); -// FURI_LOG_I(TAG, "Msg done %d", instance->msg_len); + pocsag_message_done(instance); pocsag_decode_address_word(instance, codeword); -// FURI_LOG_I(TAG, "Address: %" PRIu32 , instance->addr); -// FURI_LOG_I(TAG, "Function: %" PRIu8, instance->func); } else { -// FURI_LOG_I(TAG, "Msg"); if (!pocsag_decode_message_word(instance, codeword)) { instance->decoder.parser_step = PocsagDecoderStepFoundPreamble; -// FURI_LOG_I(TAG, "Msg done %d", instance->msg_len); pocsag_message_done(instance); } } @@ -245,29 +237,29 @@ uint8_t subghz_protocol_decoder_pocsag_get_hash_data(void* context) { SubGhzProtocolDecoderPocsag* instance = context; uint8_t hash = 0; - for(size_t i = 0; i < furi_string_size(instance->msg); i++) - hash ^= furi_string_get_char(instance->msg, i); + for(size_t i = 0; i < furi_string_size(instance->done_msg); i++) + hash ^= furi_string_get_char(instance->done_msg, i); // address is 21 bit - hash ^= (instance->ric & 0xFF) ^ - ((instance->ric >> 8) & 0xFF) ^ - ((instance->ric >> 16) & 0xFF); + hash ^= (instance->done_ric & 0xFF) ^ + ((instance->done_ric >> 8) & 0xFF) ^ + ((instance->done_ric >> 16) & 0xFF); return hash; } bool subghz_protocol_decoder_pocsag_serialize(void* context, FlipperFormat* flipper_format, SubGhzRadioPreset* preset) { furi_assert(context); SubGhzProtocolDecoderPocsag* instance = context; - FURI_LOG_I(TAG, "ser: %d", furi_string_size(instance->msg)); + FURI_LOG_I(TAG, "ser: %s", furi_string_get_cstr(instance->done_msg)); if(!subghz_block_generic_serialize(&instance->generic, flipper_format, preset)) return false; - if(!flipper_format_write_uint32(flipper_format, "RIC", &instance->ric, 1)) { + if(!flipper_format_write_uint32(flipper_format, "RIC", &instance->done_ric, 1)) { FURI_LOG_E(TAG, "Error adding RIC"); return false; } - if(!flipper_format_write_string(flipper_format, "Msg", instance->msg)) { + if(!flipper_format_write_string(flipper_format, "Msg", instance->done_msg)) { FURI_LOG_E(TAG, "Error adding Msg"); return false; } @@ -287,12 +279,12 @@ bool subghz_protocol_decoder_pocsag_deserialize(void* context, FlipperFormat* fl FURI_LOG_E(TAG, "Missing RIC"); break; } - if(!flipper_format_read_string(flipper_format, "Msg", instance->msg)) { + if(!flipper_format_read_string(flipper_format, "Msg", instance->done_msg)) { FURI_LOG_E(TAG, "Missing Msg"); break; } - FURI_LOG_I(TAG, "deser: %d", furi_string_size(instance->msg)); - FURI_LOG_I(TAG, "deser: %s", furi_string_get_cstr(instance->msg)); + FURI_LOG_I(TAG, "deser: %d", furi_string_size(instance->done_msg)); + FURI_LOG_I(TAG, "deser: %s", furi_string_get_cstr(instance->done_msg)); ret = true; } while(false); return ret; @@ -309,7 +301,7 @@ void subhz_protocol_decoder_pocsag_get_string(void* context, FuriString* output) instance->generic.protocol_name, instance->ric ); - furi_string_cat(output, instance->msg); + furi_string_cat(output, instance->done_msg); FURI_LOG_I(TAG, "str: %s", furi_string_get_cstr(output)); }