From 6a9bdeae3e51e8629bd777a7d39f205a3e727f8d Mon Sep 17 00:00:00 2001 From: SkorP Date: Tue, 25 Apr 2023 11:22:35 +0400 Subject: [PATCH] WS: add CRC, refactoring --- .../protocols/protocol_items.c | 2 +- .../protocols/protocol_items.h | 2 +- .../weather_station/protocols/wendox._w6726.c | 291 ++++++++++++++++++ .../weather_station/protocols/wendox.c | 248 --------------- .../weather_station/protocols/wendox.h | 80 ----- .../weather_station/protocols/wendox_w6726.h | 80 +++++ 6 files changed, 373 insertions(+), 330 deletions(-) create mode 100644 applications/external/weather_station/protocols/wendox._w6726.c delete mode 100644 applications/external/weather_station/protocols/wendox.c delete mode 100644 applications/external/weather_station/protocols/wendox.h create mode 100644 applications/external/weather_station/protocols/wendox_w6726.h diff --git a/applications/external/weather_station/protocols/protocol_items.c b/applications/external/weather_station/protocols/protocol_items.c index 098014703..cd4bae76d 100644 --- a/applications/external/weather_station/protocols/protocol_items.c +++ b/applications/external/weather_station/protocols/protocol_items.c @@ -16,7 +16,7 @@ const SubGhzProtocol* weather_station_protocol_registry_items[] = { &ws_protocol_auriol_th, &ws_protocol_oregon_v1, &ws_protocol_tx_8300, - &ws_protocol_wendox, + &ws_protocol_wendox_w6726, }; const SubGhzProtocolRegistry weather_station_protocol_registry = { diff --git a/applications/external/weather_station/protocols/protocol_items.h b/applications/external/weather_station/protocols/protocol_items.h index 2268150f2..0398c11f2 100644 --- a/applications/external/weather_station/protocols/protocol_items.h +++ b/applications/external/weather_station/protocols/protocol_items.h @@ -16,6 +16,6 @@ #include "auriol_hg0601a.h" #include "oregon_v1.h" #include "tx_8300.h" -#include "wendox.h" +#include "wendox_w6726.h" extern const SubGhzProtocolRegistry weather_station_protocol_registry; diff --git a/applications/external/weather_station/protocols/wendox._w6726.c b/applications/external/weather_station/protocols/wendox._w6726.c new file mode 100644 index 000000000..3976f6a37 --- /dev/null +++ b/applications/external/weather_station/protocols/wendox._w6726.c @@ -0,0 +1,291 @@ +#include "wendox_w6726.h" + +#define TAG "WSProtocolWendoxW6726" + +/* + * Wendox W6726 + * + * Temperature -50°Ñ to +70°Ñ + * _ _ _ __ _ + * _| |___| |___| |___ ... | |_| |__...._______________ + * preamble data guard time + * + * 3 reps every 3 minutes + * in the first message 11 bytes of the preamble in the rest by 7 + * + * bit 0: 1955-hi, 5865-lo + * bit 1: 5865-hi, 1955-lo + * + * guard time: 12*1955+(lo last bit) + * data: 29 bit + */ + +static const SubGhzBlockConst ws_protocol_wendox_w6726_const = { + .te_short = 1955, + .te_long = 5865, + .te_delta = 300, + .min_count_bit_for_found = 29, +}; + +struct WSProtocolDecoderWendoxW6726 { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + WSBlockGeneric generic; + + uint16_t header_count; +}; + +struct WSProtocolEncoderWendoxW6726 { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + WSBlockGeneric generic; +}; + +typedef enum { + WendoxW6726DecoderStepReset = 0, + WendoxW6726DecoderStepCheckPreambule, + WendoxW6726DecoderStepSaveDuration, + WendoxW6726DecoderStepCheckDuration, +} WendoxW6726DecoderStep; + +const SubGhzProtocolDecoder ws_protocol_wendox_w6726_decoder = { + .alloc = ws_protocol_decoder_wendox_w6726_alloc, + .free = ws_protocol_decoder_wendox_w6726_free, + + .feed = ws_protocol_decoder_wendox_w6726_feed, + .reset = ws_protocol_decoder_wendox_w6726_reset, + + .get_hash_data = ws_protocol_decoder_wendox_w6726_get_hash_data, + .serialize = ws_protocol_decoder_wendox_w6726_serialize, + .deserialize = ws_protocol_decoder_wendox_w6726_deserialize, + .get_string = ws_protocol_decoder_wendox_w6726_get_string, +}; + +const SubGhzProtocolEncoder ws_protocol_wendox_w6726_encoder = { + .alloc = NULL, + .free = NULL, + + .deserialize = NULL, + .stop = NULL, + .yield = NULL, +}; + +const SubGhzProtocol ws_protocol_wendox_w6726 = { + .name = WS_PROTOCOL_WENDOX_W6726_NAME, + .type = SubGhzProtocolWeatherStation, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + + .decoder = &ws_protocol_wendox_w6726_decoder, + .encoder = &ws_protocol_wendox_w6726_encoder, +}; + +void* ws_protocol_decoder_wendox_w6726_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + WSProtocolDecoderWendoxW6726* instance = malloc(sizeof(WSProtocolDecoderWendoxW6726)); + instance->base.protocol = &ws_protocol_wendox_w6726; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void ws_protocol_decoder_wendox_w6726_free(void* context) { + furi_assert(context); + WSProtocolDecoderWendoxW6726* instance = context; + free(instance); +} + +void ws_protocol_decoder_wendox_w6726_reset(void* context) { + furi_assert(context); + WSProtocolDecoderWendoxW6726* instance = context; + instance->decoder.parser_step = WendoxW6726DecoderStepReset; +} + +static bool ws_protocol_wendox_w6726_check(WSProtocolDecoderWendoxW6726* instance) { + if(!instance->decoder.decode_data) return false; + uint8_t msg[] = { + instance->decoder.decode_data >> 28, + instance->decoder.decode_data >> 20, + instance->decoder.decode_data >> 12, + instance->decoder.decode_data >> 4}; + + uint8_t crc = subghz_protocol_blocks_crc4(msg, 4, 0x9, 0xD); + return (crc == (instance->decoder.decode_data & 0x0F)); +} + +/** + * Analysis of received data + * @param instance Pointer to a WSBlockGeneric* instance + */ +static void ws_protocol_wendox_w6726_remote_controller(WSBlockGeneric* instance) { + instance->id = (instance->data >> 24) & 0xFF; + instance->battery_low = (instance->data >> 6) & 1; + instance->channel = WS_NO_CHANNEL; + + if(((instance->data >> 23) & 1)) { + instance->temp = (float)(((instance->data >> 14) & 0x1FF) + 12) / 10.0f; + } else { + instance->temp = (float)((~(instance->data >> 14) & 0x1FF) + 1 - 12) / -10.0f; + } + + if(instance->temp < -50.0f) { + instance->temp = -50.0f; + } else if(instance->temp > 70.0f) { + instance->temp = 70.0f; + } + + instance->btn = WS_NO_BTN; + instance->humidity = WS_NO_HUMIDITY; +} + +void ws_protocol_decoder_wendox_w6726_feed(void* context, bool level, uint32_t duration) { + furi_assert(context); + WSProtocolDecoderWendoxW6726* instance = context; + + switch(instance->decoder.parser_step) { + case WendoxW6726DecoderStepReset: + if((level) && (DURATION_DIFF(duration, ws_protocol_wendox_w6726_const.te_short) < + ws_protocol_wendox_w6726_const.te_delta)) { + instance->decoder.parser_step = WendoxW6726DecoderStepCheckPreambule; + instance->decoder.te_last = duration; + instance->header_count = 0; + } + break; + + case WendoxW6726DecoderStepCheckPreambule: + if(level) { + instance->decoder.te_last = duration; + } else { + if((DURATION_DIFF(instance->decoder.te_last, ws_protocol_wendox_w6726_const.te_short) < + ws_protocol_wendox_w6726_const.te_delta * 1) && + (DURATION_DIFF(duration, ws_protocol_wendox_w6726_const.te_long) < + ws_protocol_wendox_w6726_const.te_delta * 2)) { + instance->header_count++; + } else if((instance->header_count > 4) && (instance->header_count < 12)) { + if((DURATION_DIFF( + instance->decoder.te_last, ws_protocol_wendox_w6726_const.te_long) < + ws_protocol_wendox_w6726_const.te_delta * 2) && + (DURATION_DIFF(duration, ws_protocol_wendox_w6726_const.te_short) < + ws_protocol_wendox_w6726_const.te_delta)) { + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = WendoxW6726DecoderStepSaveDuration; + } else { + instance->decoder.parser_step = WendoxW6726DecoderStepReset; + } + + } else { + instance->decoder.parser_step = WendoxW6726DecoderStepReset; + } + } + break; + + case WendoxW6726DecoderStepSaveDuration: + if(level) { + instance->decoder.te_last = duration; + instance->decoder.parser_step = WendoxW6726DecoderStepCheckDuration; + } else { + instance->decoder.parser_step = WendoxW6726DecoderStepReset; + } + break; + + case WendoxW6726DecoderStepCheckDuration: + if(!level) { + if(duration > + ws_protocol_wendox_w6726_const.te_short + ws_protocol_wendox_w6726_const.te_long) { + if(DURATION_DIFF( + instance->decoder.te_last, ws_protocol_wendox_w6726_const.te_short) < + ws_protocol_wendox_w6726_const.te_delta) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = WendoxW6726DecoderStepSaveDuration; + } else if( + DURATION_DIFF( + instance->decoder.te_last, ws_protocol_wendox_w6726_const.te_long) < + ws_protocol_wendox_w6726_const.te_delta * 2) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = WendoxW6726DecoderStepSaveDuration; + } else { + instance->decoder.parser_step = WendoxW6726DecoderStepReset; + } + if((instance->decoder.decode_count_bit == + ws_protocol_wendox_w6726_const.min_count_bit_for_found) && + ws_protocol_wendox_w6726_check(instance)) { + instance->generic.data = instance->decoder.decode_data; + instance->generic.data_count_bit = instance->decoder.decode_count_bit; + ws_protocol_wendox_w6726_remote_controller(&instance->generic); + if(instance->base.callback) + instance->base.callback(&instance->base, instance->base.context); + } + + instance->decoder.parser_step = WendoxW6726DecoderStepReset; + } else if( + (DURATION_DIFF(instance->decoder.te_last, ws_protocol_wendox_w6726_const.te_short) < + ws_protocol_wendox_w6726_const.te_delta) && + (DURATION_DIFF(duration, ws_protocol_wendox_w6726_const.te_long) < + ws_protocol_wendox_w6726_const.te_delta * 3)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = WendoxW6726DecoderStepSaveDuration; + } else if( + (DURATION_DIFF(instance->decoder.te_last, ws_protocol_wendox_w6726_const.te_long) < + ws_protocol_wendox_w6726_const.te_delta * 2) && + (DURATION_DIFF(duration, ws_protocol_wendox_w6726_const.te_short) < + ws_protocol_wendox_w6726_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = WendoxW6726DecoderStepSaveDuration; + } else { + instance->decoder.parser_step = WendoxW6726DecoderStepReset; + } + } else { + instance->decoder.parser_step = WendoxW6726DecoderStepReset; + } + break; + } +} + +uint8_t ws_protocol_decoder_wendox_w6726_get_hash_data(void* context) { + furi_assert(context); + WSProtocolDecoderWendoxW6726* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus ws_protocol_decoder_wendox_w6726_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + WSProtocolDecoderWendoxW6726* instance = context; + return ws_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus + ws_protocol_decoder_wendox_w6726_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + WSProtocolDecoderWendoxW6726* instance = context; + return ws_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + ws_protocol_wendox_w6726_const.min_count_bit_for_found); +} + +void ws_protocol_decoder_wendox_w6726_get_string(void* context, FuriString* output) { + furi_assert(context); + WSProtocolDecoderWendoxW6726* instance = context; + furi_string_printf( + output, + "%s %dbit\r\n" + "Key:0x%lX%08lX\r\n" + "Sn:0x%lX Ch:%d Bat:%d\r\n" + "Temp:%3.1f C Hum:%d%%", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data >> 32), + (uint32_t)(instance->generic.data), + instance->generic.id, + instance->generic.channel, + instance->generic.battery_low, + (double)instance->generic.temp, + instance->generic.humidity); +} diff --git a/applications/external/weather_station/protocols/wendox.c b/applications/external/weather_station/protocols/wendox.c deleted file mode 100644 index 94e09f795..000000000 --- a/applications/external/weather_station/protocols/wendox.c +++ /dev/null @@ -1,248 +0,0 @@ -#include "wendox.h" - -#define TAG "WSProtocolWendox" - -static const SubGhzBlockConst ws_protocol_wendox_const = { - .te_short = 1955, - .te_long = 5865, - .te_delta = 300, - .min_count_bit_for_found = 28, -}; - -struct WSProtocolDecoderWendox { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - WSBlockGeneric generic; - - uint16_t header_count; -}; - -struct WSProtocolEncoderWendox { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - WSBlockGeneric generic; -}; - -typedef enum { - WendoxDecoderStepReset = 0, - WendoxDecoderStepCheckPreambule, - WendoxDecoderStepSaveDuration, - WendoxDecoderStepCheckDuration, -} WendoxDecoderStep; - -const SubGhzProtocolDecoder ws_protocol_wendox_decoder = { - .alloc = ws_protocol_decoder_wendox_alloc, - .free = ws_protocol_decoder_wendox_free, - - .feed = ws_protocol_decoder_wendox_feed, - .reset = ws_protocol_decoder_wendox_reset, - - .get_hash_data = ws_protocol_decoder_wendox_get_hash_data, - .serialize = ws_protocol_decoder_wendox_serialize, - .deserialize = ws_protocol_decoder_wendox_deserialize, - .get_string = ws_protocol_decoder_wendox_get_string, -}; - -const SubGhzProtocolEncoder ws_protocol_wendox_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol ws_protocol_wendox = { - .name = WS_PROTOCOL_WENDOX_NAME, - .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &ws_protocol_wendox_decoder, - .encoder = &ws_protocol_wendox_encoder, -}; - -void* ws_protocol_decoder_wendox_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - WSProtocolDecoderWendox* instance = malloc(sizeof(WSProtocolDecoderWendox)); - instance->base.protocol = &ws_protocol_wendox; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void ws_protocol_decoder_wendox_free(void* context) { - furi_assert(context); - WSProtocolDecoderWendox* instance = context; - free(instance); -} - -void ws_protocol_decoder_wendox_reset(void* context) { - furi_assert(context); - WSProtocolDecoderWendox* instance = context; - instance->decoder.parser_step = WendoxDecoderStepReset; -} - -// static bool ws_protocol_wendox_check(WSProtocolDecoderWendox* instance) { -// if(!instance->decoder.decode_data) return false; -// uint8_t msg[] = { -// instance->decoder.decode_data >> 24, -// instance->decoder.decode_data >> 16, -// instance->decoder.decode_data >> 8}; - -// uint8_t crc = subghz_protocol_blocks_lfsr_digest8(msg, 3, 0x98, 0xF1); -// return (crc == (instance->decoder.decode_data & 0xFF)); -// } - -/** - * Analysis of received data - * @param instance Pointer to a WSBlockGeneric* instance - */ -static void ws_protocol_wendox_remote_controller(WSBlockGeneric* instance) { - instance->id = (instance->data >> 4) & 0xFF; - instance->battery_low = (instance->data >> 5) & 1; - instance->channel = WS_NO_CHANNEL; - - if(((instance->data >> 22) & 1)) { - instance->temp = (float)(((instance->data >> 13) & 0x1FF) + 12) / 10.0f; - } else { - instance->temp = (float)((~(instance->data >> 13) & 0x1FF) + 1 - 12) / -10.0f; - } - FURI_LOG_E("TAG", "%llX %f", instance->data, (double)instance->temp); - - instance->btn = WS_NO_BTN; - instance->humidity = WS_NO_HUMIDITY; -} - -void ws_protocol_decoder_wendox_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - WSProtocolDecoderWendox* instance = context; - - switch(instance->decoder.parser_step) { - case WendoxDecoderStepReset: - if((level) && (DURATION_DIFF(duration, ws_protocol_wendox_const.te_short) < - ws_protocol_wendox_const.te_delta)) { - instance->decoder.parser_step = WendoxDecoderStepCheckPreambule; - instance->decoder.te_last = duration; - instance->header_count = 0; - } - break; - - case WendoxDecoderStepCheckPreambule: - if(level) { - instance->decoder.te_last = duration; - } else { - if((DURATION_DIFF(instance->decoder.te_last, ws_protocol_wendox_const.te_short) < - ws_protocol_wendox_const.te_delta * 1) && - (DURATION_DIFF(duration, ws_protocol_wendox_const.te_long) < - ws_protocol_wendox_const.te_delta * 2)) { - instance->header_count++; - } else if((instance->header_count > 4) && (instance->header_count < 12)) { - if((DURATION_DIFF(instance->decoder.te_last, ws_protocol_wendox_const.te_long) < - ws_protocol_wendox_const.te_delta * 2) && - (DURATION_DIFF(duration, ws_protocol_wendox_const.te_short) < - ws_protocol_wendox_const.te_delta)) { - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = WendoxDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = WendoxDecoderStepReset; - } - - } else { - instance->decoder.parser_step = WendoxDecoderStepReset; - } - } - break; - - case WendoxDecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = WendoxDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = WendoxDecoderStepReset; - } - break; - - case WendoxDecoderStepCheckDuration: - if(!level) { - if(duration > ws_protocol_wendox_const.te_short + ws_protocol_wendox_const.te_long) { - if(instance->decoder.decode_count_bit == - ws_protocol_wendox_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - ws_protocol_wendox_remote_controller(&instance->generic); - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - - instance->decoder.parser_step = WendoxDecoderStepReset; - } else if( - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_wendox_const.te_short) < - ws_protocol_wendox_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_wendox_const.te_long) < - ws_protocol_wendox_const.te_delta * 3)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = WendoxDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_wendox_const.te_long) < - ws_protocol_wendox_const.te_delta * 2) && - (DURATION_DIFF(duration, ws_protocol_wendox_const.te_short) < - ws_protocol_wendox_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = WendoxDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = WendoxDecoderStepReset; - } - } else { - instance->decoder.parser_step = WendoxDecoderStepReset; - } - break; - } -} - -uint8_t ws_protocol_decoder_wendox_get_hash_data(void* context) { - furi_assert(context); - WSProtocolDecoderWendox* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus ws_protocol_decoder_wendox_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - WSProtocolDecoderWendox* instance = context; - return ws_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -SubGhzProtocolStatus - ws_protocol_decoder_wendox_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - WSProtocolDecoderWendox* instance = context; - return ws_block_generic_deserialize_check_count_bit( - &instance->generic, flipper_format, ws_protocol_wendox_const.min_count_bit_for_found); -} - -void ws_protocol_decoder_wendox_get_string(void* context, FuriString* output) { - furi_assert(context); - WSProtocolDecoderWendox* instance = context; - furi_string_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%lX Ch:%d Bat:%d\r\n" - "Temp:%3.1f C Hum:%d%%", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)(instance->generic.data), - instance->generic.id, - instance->generic.channel, - instance->generic.battery_low, - (double)instance->generic.temp, - instance->generic.humidity); -} diff --git a/applications/external/weather_station/protocols/wendox.h b/applications/external/weather_station/protocols/wendox.h deleted file mode 100644 index 698ac0bc0..000000000 --- a/applications/external/weather_station/protocols/wendox.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include "ws_generic.h" -#include - -#define WS_PROTOCOL_WENDOX_NAME "Wendox" - -typedef struct WSProtocolDecoderWendox WSProtocolDecoderWendox; -typedef struct WSProtocolEncoderWendox WSProtocolEncoderWendox; - -extern const SubGhzProtocolDecoder ws_protocol_wendox_decoder; -extern const SubGhzProtocolEncoder ws_protocol_wendox_encoder; -extern const SubGhzProtocol ws_protocol_wendox; - -/** - * Allocate WSProtocolDecoderWendox. - * @param environment Pointer to a SubGhzEnvironment instance - * @return WSProtocolDecoderWendox* pointer to a WSProtocolDecoderWendox instance - */ -void* ws_protocol_decoder_wendox_alloc(SubGhzEnvironment* environment); - -/** - * Free WSProtocolDecoderWendox. - * @param context Pointer to a WSProtocolDecoderWendox instance - */ -void ws_protocol_decoder_wendox_free(void* context); - -/** - * Reset decoder WSProtocolDecoderWendox. - * @param context Pointer to a WSProtocolDecoderWendox instance - */ -void ws_protocol_decoder_wendox_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a WSProtocolDecoderWendox instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void ws_protocol_decoder_wendox_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a WSProtocolDecoderWendox instance - * @return hash Hash sum - */ -uint8_t ws_protocol_decoder_wendox_get_hash_data(void* context); - -/** - * Serialize data WSProtocolDecoderWendox. - * @param context Pointer to a WSProtocolDecoderWendox instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return status - */ -SubGhzProtocolStatus ws_protocol_decoder_wendox_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data WSProtocolDecoderWendox. - * @param context Pointer to a WSProtocolDecoderWendox instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return status - */ -SubGhzProtocolStatus - ws_protocol_decoder_wendox_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a WSProtocolDecoderWendox instance - * @param output Resulting text - */ -void ws_protocol_decoder_wendox_get_string(void* context, FuriString* output); diff --git a/applications/external/weather_station/protocols/wendox_w6726.h b/applications/external/weather_station/protocols/wendox_w6726.h new file mode 100644 index 000000000..236777a1c --- /dev/null +++ b/applications/external/weather_station/protocols/wendox_w6726.h @@ -0,0 +1,80 @@ +#pragma once + +#include + +#include +#include +#include +#include "ws_generic.h" +#include + +#define WS_PROTOCOL_WENDOX_W6726_NAME "Wendox W6726" + +typedef struct WSProtocolDecoderWendoxW6726 WSProtocolDecoderWendoxW6726; +typedef struct WSProtocolEncoderWendoxW6726 WSProtocolEncoderWendoxW6726; + +extern const SubGhzProtocolDecoder ws_protocol_wendox_w6726_decoder; +extern const SubGhzProtocolEncoder ws_protocol_wendox_w6726_encoder; +extern const SubGhzProtocol ws_protocol_wendox_w6726; + +/** + * Allocate WSProtocolDecoderWendoxW6726. + * @param environment Pointer to a SubGhzEnvironment instance + * @return WSProtocolDecoderWendoxW6726* pointer to a WSProtocolDecoderWendoxW6726 instance + */ +void* ws_protocol_decoder_wendox_w6726_alloc(SubGhzEnvironment* environment); + +/** + * Free WSProtocolDecoderWendoxW6726. + * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance + */ +void ws_protocol_decoder_wendox_w6726_free(void* context); + +/** + * Reset decoder WSProtocolDecoderWendoxW6726. + * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance + */ +void ws_protocol_decoder_wendox_w6726_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void ws_protocol_decoder_wendox_w6726_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance + * @return hash Hash sum + */ +uint8_t ws_protocol_decoder_wendox_w6726_get_hash_data(void* context); + +/** + * Serialize data WSProtocolDecoderWendoxW6726. + * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param preset The modulation on which the signal was received, SubGhzRadioPreset + * @return status + */ +SubGhzProtocolStatus ws_protocol_decoder_wendox_w6726_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data WSProtocolDecoderWendoxW6726. + * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + ws_protocol_decoder_wendox_w6726_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance + * @param output Resulting text + */ +void ws_protocol_decoder_wendox_w6726_get_string(void* context, FuriString* output);