SubGhz: add potocol Hormann HSM 868Mhz (#795)
* SubGhz: add decoder Normann * SubGhz: rename normann -> hormann * SubGhz: add encoder hormann * SubGhz: delete comment Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									146cd51894
								
							
						
					
					
						commit
						3f93a0ae46
					
				
							
								
								
									
										254
									
								
								lib/subghz/protocols/subghz_protocol_hormann.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										254
									
								
								lib/subghz/protocols/subghz_protocol_hormann.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,254 @@ | |||||||
|  | #include "subghz_protocol_hormann.h" | ||||||
|  | #include "subghz_protocol_common.h" | ||||||
|  | 
 | ||||||
|  | struct SubGhzProtocolHormann { | ||||||
|  |     SubGhzProtocolCommon common; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | typedef enum { | ||||||
|  |     HormannDecoderStepReset = 0, | ||||||
|  |     HormannDecoderStepFoundStartHeader, | ||||||
|  |     HormannDecoderStepFoundHeader, | ||||||
|  |     HormannDecoderStepFoundStartBit, | ||||||
|  |     HormannDecoderStepSaveDuration, | ||||||
|  |     HormannDecoderStepCheckDuration, | ||||||
|  | } HormannDecoderStep; | ||||||
|  | 
 | ||||||
|  | SubGhzProtocolHormann* subghz_protocol_hormann_alloc() { | ||||||
|  |     SubGhzProtocolHormann* instance = furi_alloc(sizeof(SubGhzProtocolHormann)); | ||||||
|  | 
 | ||||||
|  |     instance->common.name = "Hormann HSM"; | ||||||
|  |     instance->common.code_min_count_bit_for_found = 44; | ||||||
|  |     instance->common.te_short = 511; | ||||||
|  |     instance->common.te_long = 1022; | ||||||
|  |     instance->common.te_delta = 200; | ||||||
|  |     instance->common.type_protocol = SubGhzProtocolCommonTypeStatic; | ||||||
|  |     instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_hormann_to_str; | ||||||
|  |     instance->common.to_save_string = | ||||||
|  |         (SubGhzProtocolCommonGetStrSave)subghz_protocol_hormann_to_save_str; | ||||||
|  |     instance->common.to_load_protocol_from_file = | ||||||
|  |         (SubGhzProtocolCommonLoadFromFile)subghz_protocol_hormann_to_load_protocol_from_file; | ||||||
|  |     instance->common.to_load_protocol = | ||||||
|  |         (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_hormann_to_load_protocol; | ||||||
|  |     instance->common.get_upload_protocol = | ||||||
|  |         (SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_hormann_send_key; | ||||||
|  | 
 | ||||||
|  |     return instance; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void subghz_protocol_hormann_free(SubGhzProtocolHormann* instance) { | ||||||
|  |     furi_assert(instance); | ||||||
|  |     free(instance); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool subghz_protocol_hormann_send_key( | ||||||
|  |     SubGhzProtocolHormann* instance, | ||||||
|  |     SubGhzProtocolCommonEncoder* encoder) { | ||||||
|  |     furi_assert(instance); | ||||||
|  |     furi_assert(encoder); | ||||||
|  | 
 | ||||||
|  |     size_t index = 0; | ||||||
|  |     encoder->size_upload = 3 + (instance->common.code_last_count_bit * 2 + 2) * 20 + 1; | ||||||
|  |     if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false; | ||||||
|  |     //Send header
 | ||||||
|  |     encoder->upload[index++] = | ||||||
|  |         level_duration_make(false, (uint32_t)instance->common.te_short * 64); | ||||||
|  |     encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short * 64); | ||||||
|  |     encoder->upload[index++] = | ||||||
|  |         level_duration_make(false, (uint32_t)instance->common.te_short * 64); | ||||||
|  |     encoder->repeat = 10; | ||||||
|  | 
 | ||||||
|  |     for(size_t repeat = 0; repeat < 20; repeat++) { | ||||||
|  |         //Send start bit
 | ||||||
|  |         encoder->upload[index++] = | ||||||
|  |             level_duration_make(true, (uint32_t)instance->common.te_short * 24); | ||||||
|  |         encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); | ||||||
|  |         //Send key data
 | ||||||
|  |         for(uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { | ||||||
|  |             if(bit_read(instance->common.code_last_found, i - 1)) { | ||||||
|  |                 //send bit 1
 | ||||||
|  |                 encoder->upload[index++] = | ||||||
|  |                     level_duration_make(true, (uint32_t)instance->common.te_long); | ||||||
|  |                 encoder->upload[index++] = | ||||||
|  |                     level_duration_make(false, (uint32_t)instance->common.te_short); | ||||||
|  |             } else { | ||||||
|  |                 //send bit 0
 | ||||||
|  |                 encoder->upload[index++] = | ||||||
|  |                     level_duration_make(true, (uint32_t)instance->common.te_short); | ||||||
|  |                 encoder->upload[index++] = | ||||||
|  |                     level_duration_make(false, (uint32_t)instance->common.te_long); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short * 24); | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void subghz_protocol_hormann_reset(SubGhzProtocolHormann* instance) { | ||||||
|  |     instance->common.parser_step = HormannDecoderStepReset; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void subghz_protocol_hormann_parse(SubGhzProtocolHormann* instance, bool level, uint32_t duration) { | ||||||
|  |     switch(instance->common.parser_step) { | ||||||
|  |     case HormannDecoderStepReset: | ||||||
|  |         if((level) && (DURATION_DIFF(duration, instance->common.te_short * 64) < | ||||||
|  |                        instance->common.te_delta * 64)) { | ||||||
|  |             instance->common.parser_step = HormannDecoderStepFoundStartHeader; | ||||||
|  |         } else { | ||||||
|  |             instance->common.parser_step = HormannDecoderStepReset; | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |     case HormannDecoderStepFoundStartHeader: | ||||||
|  |         if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 64) < | ||||||
|  |                         instance->common.te_delta * 64)) { | ||||||
|  |             instance->common.parser_step = HormannDecoderStepFoundHeader; | ||||||
|  |         } else { | ||||||
|  |             instance->common.parser_step = HormannDecoderStepReset; | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |     case HormannDecoderStepFoundHeader: | ||||||
|  |         if((level) && (DURATION_DIFF(duration, instance->common.te_short * 24) < | ||||||
|  |                        instance->common.te_delta * 24)) { | ||||||
|  |             instance->common.parser_step = HormannDecoderStepFoundStartBit; | ||||||
|  |         } else { | ||||||
|  |             instance->common.parser_step = HormannDecoderStepReset; | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |     case HormannDecoderStepFoundStartBit: | ||||||
|  |         if((!level) && | ||||||
|  |            (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { | ||||||
|  |             instance->common.parser_step = HormannDecoderStepSaveDuration; | ||||||
|  |             instance->common.code_found = 0; | ||||||
|  |             instance->common.code_count_bit = 0; | ||||||
|  |         } else { | ||||||
|  |             instance->common.parser_step = HormannDecoderStepReset; | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |     case HormannDecoderStepSaveDuration: | ||||||
|  |         if(level) { //save interval
 | ||||||
|  |             if(duration >= (instance->common.te_short * 5)) { | ||||||
|  |                 instance->common.parser_step = HormannDecoderStepFoundStartBit; | ||||||
|  |                 if(instance->common.code_count_bit >= | ||||||
|  |                    instance->common.code_min_count_bit_for_found) { | ||||||
|  |                     instance->common.serial = 0x0; | ||||||
|  |                     instance->common.btn = 0x0; | ||||||
|  | 
 | ||||||
|  |                     instance->common.code_last_found = instance->common.code_found; | ||||||
|  |                     instance->common.code_last_count_bit = instance->common.code_count_bit; | ||||||
|  | 
 | ||||||
|  |                     if(instance->common.callback) | ||||||
|  |                         instance->common.callback( | ||||||
|  |                             (SubGhzProtocolCommon*)instance, instance->common.context); | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             instance->common.te_last = duration; | ||||||
|  |             instance->common.parser_step = HormannDecoderStepCheckDuration; | ||||||
|  |         } else { | ||||||
|  |             instance->common.parser_step = HormannDecoderStepReset; | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |     case HormannDecoderStepCheckDuration: | ||||||
|  |         if(!level) { | ||||||
|  |             if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < | ||||||
|  |                 instance->common.te_delta) && | ||||||
|  |                (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { | ||||||
|  |                 subghz_protocol_common_add_bit(&instance->common, 0); | ||||||
|  |                 instance->common.parser_step = HormannDecoderStepSaveDuration; | ||||||
|  |             } else if( | ||||||
|  |                 (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < | ||||||
|  |                  instance->common.te_delta) && | ||||||
|  |                 (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { | ||||||
|  |                 subghz_protocol_common_add_bit(&instance->common, 1); | ||||||
|  |                 instance->common.parser_step = HormannDecoderStepSaveDuration; | ||||||
|  |             } else | ||||||
|  |                 instance->common.parser_step = HormannDecoderStepReset; | ||||||
|  |         } else { | ||||||
|  |             instance->common.parser_step = HormannDecoderStepReset; | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void subghz_protocol_hormann_to_str(SubGhzProtocolHormann* instance, string_t output) { | ||||||
|  |     uint32_t code_found_hi = instance->common.code_last_found >> 32; | ||||||
|  |     uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff; | ||||||
|  |     instance->common.btn = (instance->common.code_last_found >> 4) & 0xF; | ||||||
|  | 
 | ||||||
|  |     string_cat_printf( | ||||||
|  |         output, | ||||||
|  |         "%s\r\n" | ||||||
|  |         "%dbit\r\n" | ||||||
|  |         "Key:0x%03lX%08lX\r\n" | ||||||
|  |         "Btn:0x%01X", | ||||||
|  |         instance->common.name, | ||||||
|  |         instance->common.code_last_count_bit, | ||||||
|  |         code_found_hi, | ||||||
|  |         code_found_lo, | ||||||
|  |         instance->common.btn); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void subghz_protocol_hormann_to_save_str(SubGhzProtocolHormann* instance, string_t output) { | ||||||
|  |     string_printf( | ||||||
|  |         output, | ||||||
|  |         "Protocol: %s\n" | ||||||
|  |         "Bit: %d\n" | ||||||
|  |         "Key: %08lX%08lX\n", | ||||||
|  |         instance->common.name, | ||||||
|  |         instance->common.code_last_count_bit, | ||||||
|  |         (uint32_t)(instance->common.code_last_found >> 32), | ||||||
|  |         (uint32_t)(instance->common.code_last_found & 0x00000000ffffffff)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool subghz_protocol_hormann_to_load_protocol_from_file( | ||||||
|  |     FileWorker* file_worker, | ||||||
|  |     SubGhzProtocolHormann* instance, | ||||||
|  |     const char* file_path) { | ||||||
|  |     bool loaded = false; | ||||||
|  |     string_t temp_str; | ||||||
|  |     string_init(temp_str); | ||||||
|  |     int res = 0; | ||||||
|  |     int data = 0; | ||||||
|  | 
 | ||||||
|  |     do { | ||||||
|  |         // Read and parse bit data from 2nd line
 | ||||||
|  |         if(!file_worker_read_until(file_worker, temp_str, '\n')) { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data); | ||||||
|  |         if(res != 1) { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         instance->common.code_last_count_bit = (uint8_t)data; | ||||||
|  | 
 | ||||||
|  |         // Read and parse key data from 3nd line
 | ||||||
|  |         if(!file_worker_read_until(file_worker, temp_str, '\n')) { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         // strlen("Key: ") = 5
 | ||||||
|  |         string_right(temp_str, 5); | ||||||
|  | 
 | ||||||
|  |         uint8_t buf_key[8] = {0}; | ||||||
|  |         if(!subghz_protocol_common_read_hex(temp_str, buf_key, 8)) { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         for(uint8_t i = 0; i < 8; i++) { | ||||||
|  |             instance->common.code_last_found = instance->common.code_last_found << 8 | buf_key[i]; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         loaded = true; | ||||||
|  |     } while(0); | ||||||
|  | 
 | ||||||
|  |     string_clear(temp_str); | ||||||
|  | 
 | ||||||
|  |     return loaded; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void subghz_decoder_hormann_to_load_protocol(SubGhzProtocolHormann* instance, void* context) { | ||||||
|  |     furi_assert(context); | ||||||
|  |     furi_assert(instance); | ||||||
|  |     SubGhzProtocolCommonLoad* data = context; | ||||||
|  |     instance->common.code_last_found = data->code_found; | ||||||
|  |     instance->common.code_last_count_bit = data->code_count_bit; | ||||||
|  | } | ||||||
							
								
								
									
										72
									
								
								lib/subghz/protocols/subghz_protocol_hormann.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								lib/subghz/protocols/subghz_protocol_hormann.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,72 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "subghz_protocol_common.h" | ||||||
|  | 
 | ||||||
|  | typedef struct SubGhzProtocolHormann SubGhzProtocolHormann; | ||||||
|  | 
 | ||||||
|  | /** Allocate SubGhzProtocolHormann
 | ||||||
|  |  *  | ||||||
|  |  * @return SubGhzProtocolHormann*  | ||||||
|  |  */ | ||||||
|  | SubGhzProtocolHormann* subghz_protocol_hormann_alloc(); | ||||||
|  | 
 | ||||||
|  | /** Free SubGhzProtocolHormann
 | ||||||
|  |  *  | ||||||
|  |  * @param instance  | ||||||
|  |  */ | ||||||
|  | void subghz_protocol_hormann_free(SubGhzProtocolHormann* instance); | ||||||
|  | 
 | ||||||
|  | /** Get upload protocol
 | ||||||
|  |  *  | ||||||
|  |  * @param instance - SubGhzProtocolHormann instance | ||||||
|  |  * @param encoder - SubGhzProtocolCommonEncoder encoder | ||||||
|  |  * @return bool | ||||||
|  |  */ | ||||||
|  | bool subghz_protocol_hormann_send_key( | ||||||
|  |     SubGhzProtocolHormann* instance, | ||||||
|  |     SubGhzProtocolCommonEncoder* encoder); | ||||||
|  | 
 | ||||||
|  | /** Reset internal state
 | ||||||
|  |  * @param instance - SubGhzProtocolHormann instance | ||||||
|  |  */ | ||||||
|  | void subghz_protocol_hormann_reset(SubGhzProtocolHormann* instance); | ||||||
|  | 
 | ||||||
|  | /** Parse accepted duration
 | ||||||
|  |  *  | ||||||
|  |  * @param instance - SubGhzProtocolHormann instance | ||||||
|  |  * @param data - LevelDuration level_duration | ||||||
|  |  */ | ||||||
|  | void subghz_protocol_hormann_parse(SubGhzProtocolHormann* instance, bool level, uint32_t duration); | ||||||
|  | 
 | ||||||
|  | /** Outputting information from the parser
 | ||||||
|  |  *  | ||||||
|  |  * @param instance - SubGhzProtocolHormann* instance | ||||||
|  |  * @param output   - output string | ||||||
|  |  */ | ||||||
|  | void subghz_protocol_hormann_to_str(SubGhzProtocolHormann* instance, string_t output); | ||||||
|  | 
 | ||||||
|  | /** Get a string to save the protocol
 | ||||||
|  |  *  | ||||||
|  |  * @param instance  - SubGhzProtocolHormann instance | ||||||
|  |  * @param output    - the resulting string | ||||||
|  |  */ | ||||||
|  | void subghz_protocol_hormann_to_save_str(SubGhzProtocolHormann* instance, string_t output); | ||||||
|  | 
 | ||||||
|  | /** Loading protocol from file
 | ||||||
|  |  *  | ||||||
|  |  * @param file_worker - FileWorker file_worker | ||||||
|  |  * @param instance - SubGhzProtocolHormann instance | ||||||
|  |  * @param file_path - file path | ||||||
|  |  * @return bool | ||||||
|  |  */ | ||||||
|  | bool subghz_protocol_hormann_to_load_protocol_from_file( | ||||||
|  |     FileWorker* file_worker, | ||||||
|  |     SubGhzProtocolHormann* instance, | ||||||
|  |     const char* file_path); | ||||||
|  | 
 | ||||||
|  | /** Loading protocol from bin data
 | ||||||
|  |  *  | ||||||
|  |  * @param instance - SubGhzProtocolHormann instance | ||||||
|  |  * @param context - SubGhzProtocolCommonLoad context | ||||||
|  |  */ | ||||||
|  | void subghz_decoder_hormann_to_load_protocol(SubGhzProtocolHormann* instance, void* context); | ||||||
| @ -17,6 +17,7 @@ | |||||||
| #include "protocols/subghz_protocol_scher_khan.h" | #include "protocols/subghz_protocol_scher_khan.h" | ||||||
| #include "protocols/subghz_protocol_kia.h" | #include "protocols/subghz_protocol_kia.h" | ||||||
| #include "protocols/subghz_protocol_raw.h" | #include "protocols/subghz_protocol_raw.h" | ||||||
|  | #include "protocols/subghz_protocol_hormann.h" | ||||||
| 
 | 
 | ||||||
| #include "subghz_keystore.h" | #include "subghz_keystore.h" | ||||||
| 
 | 
 | ||||||
| @ -40,6 +41,7 @@ typedef enum { | |||||||
|     SubGhzProtocolTypeScherKhan, |     SubGhzProtocolTypeScherKhan, | ||||||
|     SubGhzProtocolTypeKIA, |     SubGhzProtocolTypeKIA, | ||||||
|     SubGhzProtocolTypeRAW, |     SubGhzProtocolTypeRAW, | ||||||
|  |     SubGhzProtocolTypeHormann, | ||||||
| 
 | 
 | ||||||
|     SubGhzProtocolTypeMax, |     SubGhzProtocolTypeMax, | ||||||
| } SubGhzProtocolType; | } SubGhzProtocolType; | ||||||
| @ -113,6 +115,8 @@ SubGhzParser* subghz_parser_alloc() { | |||||||
|         (SubGhzProtocolCommon*)subghz_protocol_kia_alloc(); |         (SubGhzProtocolCommon*)subghz_protocol_kia_alloc(); | ||||||
|     instance->protocols[SubGhzProtocolTypeRAW] = |     instance->protocols[SubGhzProtocolTypeRAW] = | ||||||
|         (SubGhzProtocolCommon*)subghz_protocol_raw_alloc(); |         (SubGhzProtocolCommon*)subghz_protocol_raw_alloc(); | ||||||
|  |     instance->protocols[SubGhzProtocolTypeHormann] = | ||||||
|  |         (SubGhzProtocolCommon*)subghz_protocol_hormann_alloc(); | ||||||
| 
 | 
 | ||||||
|     return instance; |     return instance; | ||||||
| } | } | ||||||
| @ -148,6 +152,8 @@ void subghz_parser_free(SubGhzParser* instance) { | |||||||
|         (SubGhzProtocolScherKhan*)instance->protocols[SubGhzProtocolTypeScherKhan]); |         (SubGhzProtocolScherKhan*)instance->protocols[SubGhzProtocolTypeScherKhan]); | ||||||
|     subghz_protocol_kia_free((SubGhzProtocolKIA*)instance->protocols[SubGhzProtocolTypeKIA]); |     subghz_protocol_kia_free((SubGhzProtocolKIA*)instance->protocols[SubGhzProtocolTypeKIA]); | ||||||
|     subghz_protocol_raw_free((SubGhzProtocolRAW*)instance->protocols[SubGhzProtocolTypeRAW]); |     subghz_protocol_raw_free((SubGhzProtocolRAW*)instance->protocols[SubGhzProtocolTypeRAW]); | ||||||
|  |     subghz_protocol_hormann_free( | ||||||
|  |         (SubGhzProtocolHormann*)instance->protocols[SubGhzProtocolTypeHormann]); | ||||||
| 
 | 
 | ||||||
|     subghz_keystore_free(instance->keystore); |     subghz_keystore_free(instance->keystore); | ||||||
| 
 | 
 | ||||||
| @ -240,6 +246,8 @@ void subghz_parser_reset(SubGhzParser* instance) { | |||||||
|         (SubGhzProtocolScherKhan*)instance->protocols[SubGhzProtocolTypeScherKhan]); |         (SubGhzProtocolScherKhan*)instance->protocols[SubGhzProtocolTypeScherKhan]); | ||||||
|     subghz_protocol_kia_reset((SubGhzProtocolKIA*)instance->protocols[SubGhzProtocolTypeKIA]); |     subghz_protocol_kia_reset((SubGhzProtocolKIA*)instance->protocols[SubGhzProtocolTypeKIA]); | ||||||
|     subghz_protocol_raw_reset((SubGhzProtocolRAW*)instance->protocols[SubGhzProtocolTypeRAW]); |     subghz_protocol_raw_reset((SubGhzProtocolRAW*)instance->protocols[SubGhzProtocolTypeRAW]); | ||||||
|  |     subghz_protocol_hormann_reset( | ||||||
|  |         (SubGhzProtocolHormann*)instance->protocols[SubGhzProtocolTypeHormann]); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void subghz_parser_raw_parse(SubGhzParser* instance, bool level, uint32_t duration) { | void subghz_parser_raw_parse(SubGhzParser* instance, bool level, uint32_t duration) { | ||||||
| @ -290,4 +298,6 @@ void subghz_parser_parse(SubGhzParser* instance, bool level, uint32_t duration) | |||||||
|         duration); |         duration); | ||||||
|     subghz_protocol_kia_parse( |     subghz_protocol_kia_parse( | ||||||
|         (SubGhzProtocolKIA*)instance->protocols[SubGhzProtocolTypeKIA], level, duration); |         (SubGhzProtocolKIA*)instance->protocols[SubGhzProtocolTypeKIA], level, duration); | ||||||
|  |     subghz_protocol_hormann_parse( | ||||||
|  |         (SubGhzProtocolHormann*)instance->protocols[SubGhzProtocolTypeHormann], level, duration); | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Skorpionm
						Skorpionm