Fix race condition

This commit is contained in:
Max Lapan
2022-11-21 20:29:33 +01:00
parent 6b191945fb
commit 78bbba88d2
+29 -37
View File
@@ -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));
}