mirror of
https://github.com/DarkFlippers/unleashed-firmware
synced 2024-11-27 06:50:21 +00:00
SubGhz: Nice FlooR S improvements, cli stack overflow fix, code documentation, new key data formatting (#559)
This commit is contained in:
parent
b6d5b5cb74
commit
88be176fcf
19 changed files with 454 additions and 82 deletions
|
@ -51,7 +51,7 @@ void ibutton_cli_init();
|
|||
|
||||
const FlipperApplication FLIPPER_SERVICES[] = {
|
||||
#ifdef SRV_CLI
|
||||
{.app = cli_task, .name = "cli_task", .stack_size = 2048, .icon = A_Plugins_14},
|
||||
{.app = cli_task, .name = "cli_task", .stack_size = 4096, .icon = A_Plugins_14},
|
||||
#endif
|
||||
|
||||
#ifdef SRV_EXAMPLE_BLINK
|
||||
|
|
|
@ -256,6 +256,7 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) {
|
|||
|
||||
SubGhzProtocol* protocol = subghz_protocol_alloc();
|
||||
subghz_protocol_load_keeloq_file(protocol, "/assets/subghz/keeloq_mfcodes");
|
||||
subghz_protocol_load_nice_flor_s_file(protocol, "/assets/subghz/nice_floor_s_rx");
|
||||
subghz_protocol_enable_dump(protocol, NULL, NULL);
|
||||
|
||||
frequency = api_hal_subghz_set_frequency_and_path(frequency);
|
||||
|
|
|
@ -161,6 +161,8 @@ SubghzCapture* subghz_capture_alloc() {
|
|||
subghz_worker_set_context(subghz_capture->worker, subghz_capture->protocol);
|
||||
|
||||
subghz_protocol_load_keeloq_file(subghz_capture->protocol, "/assets/subghz/keeloq_mfcodes");
|
||||
subghz_protocol_load_nice_flor_s_file(
|
||||
subghz_capture->protocol, "/assets/subghz/nice_floor_s_rx");
|
||||
subghz_protocol_enable_dump(
|
||||
subghz_capture->protocol, subghz_capture_text_callback, subghz_capture);
|
||||
|
||||
|
|
|
@ -89,6 +89,10 @@ static void subghz_protocol_load_keeloq_file_process_line(SubGhzProtocol* instan
|
|||
}
|
||||
}
|
||||
|
||||
void subghz_protocol_load_nice_flor_s_file(SubGhzProtocol* instance, const char* file_name) {
|
||||
subghz_protocol_nice_flor_s_name_file(instance->nice_flor_s, file_name);
|
||||
}
|
||||
|
||||
void subghz_protocol_load_keeloq_file(SubGhzProtocol* instance, const char* file_name) {
|
||||
File manufacture_keys_file;
|
||||
FS_Api* fs_api = furi_record_open("sdcard");
|
||||
|
|
|
@ -6,14 +6,52 @@ typedef void (*SubGhzProtocolTextCallback)(string_t text, void* context);
|
|||
|
||||
typedef struct SubGhzProtocol SubGhzProtocol;
|
||||
|
||||
/** Allocate SubGhzProtocol
|
||||
*
|
||||
* @return SubGhzProtocol*
|
||||
*/
|
||||
SubGhzProtocol* subghz_protocol_alloc();
|
||||
|
||||
/** Free SubGhzProtocol
|
||||
*
|
||||
* @param instance
|
||||
*/
|
||||
void subghz_protocol_free(SubGhzProtocol* instance);
|
||||
|
||||
void subghz_protocol_enable_dump(SubGhzProtocol* instance, SubGhzProtocolTextCallback callback, void* context);
|
||||
/** Outputting data from all parsers
|
||||
*
|
||||
* @param instance - SubGhzProtocol instance
|
||||
* @param callback - SubGhzProtocolTextCallback callback
|
||||
* @param context
|
||||
*/
|
||||
void subghz_protocol_enable_dump(
|
||||
SubGhzProtocol* instance,
|
||||
SubGhzProtocolTextCallback callback,
|
||||
void* context);
|
||||
|
||||
/** File name rainbow table Nice Flor-S
|
||||
*
|
||||
* @param instance - SubGhzProtocol instance
|
||||
* @param file_name - "path/file_name"
|
||||
*/
|
||||
void subghz_protocol_load_nice_flor_s_file(SubGhzProtocol* instance, const char* file_name);
|
||||
|
||||
/** File upload manufacture keys
|
||||
*
|
||||
* @param instance - SubGhzProtocol instance
|
||||
* @param file_name - "path/file_name"
|
||||
*/
|
||||
void subghz_protocol_load_keeloq_file(SubGhzProtocol* instance, const char* file_name);
|
||||
|
||||
/** Restarting all parsers
|
||||
*
|
||||
* @param instance - SubGhzProtocol instance
|
||||
*/
|
||||
void subghz_protocol_reset(SubGhzProtocol* instance);
|
||||
|
||||
/** Loading data into all parsers
|
||||
*
|
||||
* @param instance - SubGhzProtocol instance
|
||||
* @param data - LevelPair data
|
||||
*/
|
||||
void subghz_protocol_parse(SubGhzProtocol* instance, LevelPair data);
|
||||
|
|
|
@ -28,6 +28,11 @@ void subghz_protocol_came_free(SubGhzProtocolCame* instance) {
|
|||
free(instance);
|
||||
}
|
||||
|
||||
/** Send bit
|
||||
*
|
||||
* @param instance - SubGhzProtocolCame instance
|
||||
* @param bit - bit
|
||||
*/
|
||||
void subghz_protocol_came_send_bit(SubGhzProtocolCame* instance, uint8_t bit) {
|
||||
if (bit) {
|
||||
//send bit 1
|
||||
|
@ -88,6 +93,8 @@ void subghz_protocol_came_parse(SubGhzProtocolCame* instance, LevelPair data) {
|
|||
if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
|
||||
|
||||
//ToDo out data display
|
||||
instance->common.serial = 0x0;
|
||||
instance->common.btn = 0x0;
|
||||
if (instance->common.callback)
|
||||
instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
|
||||
}
|
||||
|
|
|
@ -4,10 +4,30 @@
|
|||
|
||||
typedef struct SubGhzProtocolCame SubGhzProtocolCame;
|
||||
|
||||
/** Allocate SubGhzProtocolCame
|
||||
*
|
||||
* @return SubGhzProtocolCame*
|
||||
*/
|
||||
SubGhzProtocolCame* subghz_protocol_came_alloc();
|
||||
|
||||
/** Free SubGhzProtocolCame
|
||||
*
|
||||
* @param instance
|
||||
*/
|
||||
void subghz_protocol_came_free(SubGhzProtocolCame* instance);
|
||||
|
||||
/** Sends the key on the air
|
||||
*
|
||||
* @param instance - SubGhzProtocolCame instance
|
||||
* @param key - key send
|
||||
* @param bit - count bit key
|
||||
* @param repeat - repeat send key
|
||||
*/
|
||||
void subghz_protocol_came_send_key(SubGhzProtocolCame* instance, uint64_t key, uint8_t bit, uint8_t repeat);
|
||||
|
||||
/** Parse accepted duration
|
||||
*
|
||||
* @param instance - SubGhzProtocolCame instance
|
||||
* @param data - LevelPair data
|
||||
*/
|
||||
void subghz_protocol_came_parse(SubGhzProtocolCame* instance, LevelPair data);
|
||||
|
|
|
@ -6,11 +6,11 @@ void subghz_protocol_common_add_bit(SubGhzProtocolCommon *common, uint8_t bit){
|
|||
common->code_count_bit++;
|
||||
}
|
||||
|
||||
uint8_t subghz_protocol_common_check_interval (SubGhzProtocolCommon *common, uint32_t interval, uint16_t interval_check) {
|
||||
if ((interval_check >= (interval - common->te_delta))&&(interval_check <= (interval + common->te_delta))){
|
||||
return 1;
|
||||
bool subghz_protocol_common_check_interval (SubGhzProtocolCommon *common, uint32_t duration, uint16_t duration_check) {
|
||||
if ((duration_check >= (duration - common->te_delta))&&(duration_check <= (duration + common->te_delta))){
|
||||
return true;
|
||||
} else {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,26 +44,32 @@ void subghz_protocol_common_to_str(SubGhzProtocolCommon* instance, string_t outp
|
|||
output,
|
||||
"Protocol %s, %d Bit\r\n"
|
||||
" KEY:0x%lX%08lX\r\n"
|
||||
" YEK:0x%lX%08lX\r\n",
|
||||
" YEK:0x%lX%08lX\r\n"
|
||||
" SN:0x%05lX BTN:%02X\r\n",
|
||||
instance->name,
|
||||
instance->code_count_bit,
|
||||
code_found_hi,
|
||||
code_found_lo,
|
||||
code_found_reverse_hi,
|
||||
code_found_reverse_lo
|
||||
code_found_reverse_lo,
|
||||
instance->serial,
|
||||
instance->btn
|
||||
);
|
||||
} else {
|
||||
string_cat_printf(
|
||||
output,
|
||||
"Protocol %s, %d Bit\r\n"
|
||||
" KEY:0x%lX%lX\r\n"
|
||||
" YEK:0x%lX%lX\r\n",
|
||||
" YEK:0x%lX%lX\r\n"
|
||||
" SN:0x%05lX BTN:%02X\r\n",
|
||||
instance->name,
|
||||
instance->code_count_bit,
|
||||
code_found_hi,
|
||||
code_found_lo,
|
||||
code_found_reverse_hi,
|
||||
code_found_reverse_lo
|
||||
code_found_reverse_lo,
|
||||
instance->serial,
|
||||
instance->btn
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ struct SubGhzProtocolCommon {
|
|||
uint16_t te_last;
|
||||
uint8_t header_count;
|
||||
uint16_t cnt;
|
||||
uint32_t serial;
|
||||
uint8_t btn;
|
||||
|
||||
/* Standard Callback for on rx complete event */
|
||||
SubGhzProtocolCommonCallback callback;
|
||||
|
@ -41,13 +43,44 @@ struct SubGhzProtocolCommon {
|
|||
SubGhzProtocolCommonToStr to_string;
|
||||
};
|
||||
|
||||
|
||||
/** Add data bit to code_found
|
||||
*
|
||||
* @param common - SubGhzProtocolCommon common
|
||||
* @param bit - add bit
|
||||
*/
|
||||
void subghz_protocol_common_add_bit(SubGhzProtocolCommon *common, uint8_t bit);
|
||||
|
||||
uint8_t subghz_protocol_common_check_interval(SubGhzProtocolCommon *common, uint32_t interval, uint16_t interval_check);
|
||||
/** Checking that the duration is included in the interval
|
||||
*
|
||||
* @param common - SubGhzProtocolCommon common
|
||||
* @param duration duration reference
|
||||
* @param duration_check duration checked
|
||||
* @return true on success
|
||||
*/
|
||||
bool subghz_protocol_common_check_interval(SubGhzProtocolCommon *common, uint32_t duration, uint16_t duration_check);
|
||||
|
||||
/** Bit-by-bit data mirroring
|
||||
*
|
||||
* @param key - data to mirror
|
||||
* @param count_bit number of data bits
|
||||
* @return mirrored data
|
||||
*/
|
||||
uint64_t subghz_protocol_common_reverse_key(uint64_t key, uint8_t count_bit);
|
||||
|
||||
|
||||
/** Callback protocol
|
||||
*
|
||||
* @param instance - SubGhzProtocolCommon* instance
|
||||
* @param callback
|
||||
* @param context
|
||||
*/
|
||||
void subghz_protocol_common_set_callback(SubGhzProtocolCommon* instance, SubGhzProtocolCommonCallback callback, void* context);
|
||||
|
||||
/** outputting information from the parser
|
||||
*
|
||||
* @param instance - SubGhzProtocolCommon* instance
|
||||
* @param output - output string
|
||||
*/
|
||||
void subghz_protocol_common_to_str(SubGhzProtocolCommon* instance, string_t output);
|
||||
|
||||
|
|
|
@ -41,9 +41,9 @@ struct SubGhzProtocolKeeloq {
|
|||
};
|
||||
|
||||
/** Simple Learning Encrypt
|
||||
* @param data - serial number (28bit)
|
||||
* @param data - 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter
|
||||
* @param key - manufacture (64bit)
|
||||
* @return ?
|
||||
* @return keelog encrypt data
|
||||
*/
|
||||
inline uint32_t subghz_protocol_keeloq_encrypt(const uint32_t data, const uint64_t key) {
|
||||
uint32_t x = data, r;
|
||||
|
@ -53,9 +53,9 @@ inline uint32_t subghz_protocol_keeloq_encrypt(const uint32_t data, const uint64
|
|||
}
|
||||
|
||||
/** Simple Learning Decrypt
|
||||
* @param data - serial number (28bit)
|
||||
* @param data - keelog encrypt data
|
||||
* @param key - manufacture (64bit)
|
||||
* @return ?
|
||||
* @return 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter
|
||||
*/
|
||||
inline uint32_t subghz_protocol_keeloq_decrypt(const uint32_t data, const uint64_t key) {
|
||||
uint32_t x = data, r;
|
||||
|
@ -67,7 +67,7 @@ inline uint32_t subghz_protocol_keeloq_decrypt(const uint32_t data, const uint64
|
|||
/** Normal Learning
|
||||
* @param data - serial number (28bit)
|
||||
* @param key - manufacture (64bit)
|
||||
* @return ?
|
||||
* @return manufacture for this serial number (64bit)
|
||||
*/
|
||||
inline uint64_t subghz_protocol_keeloq_normal_learning(uint32_t data, const uint64_t key){
|
||||
uint32_t k1,k2;
|
||||
|
@ -116,6 +116,13 @@ void subghz_protocol_keeloq_add_manafacture_key(SubGhzProtocolKeeloq* instance,
|
|||
manufacture_code->type = type;
|
||||
}
|
||||
|
||||
/** Checking the accepted code against the database manafacture key
|
||||
*
|
||||
* @param instance SubGhzProtocolKeeloq instance
|
||||
* @param fix fix part of the parcel
|
||||
* @param hop hop encrypted part of the parcel
|
||||
* @return true on successful search
|
||||
*/
|
||||
uint8_t subghz_protocol_keeloq_check_remote_controller_selector(SubGhzProtocolKeeloq* instance, uint32_t fix , uint32_t hop) {
|
||||
uint16_t end_serial = (uint16_t)(fix&0x3FF);
|
||||
uint8_t btn = (uint8_t)(fix>>28);
|
||||
|
@ -200,6 +207,10 @@ uint8_t subghz_protocol_keeloq_check_remote_controller_selector(SubGhzProtocolKe
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** Analysis of received data
|
||||
*
|
||||
* @param instance SubGhzProtocolKeeloq instance
|
||||
*/
|
||||
void subghz_protocol_keeloq_check_remote_controller(SubGhzProtocolKeeloq* instance) {
|
||||
uint64_t key = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit);
|
||||
uint32_t key_fix = key >> 32;
|
||||
|
@ -211,9 +222,16 @@ void subghz_protocol_keeloq_check_remote_controller(SubGhzProtocolKeeloq* instan
|
|||
} else {
|
||||
subghz_protocol_keeloq_check_remote_controller_selector(instance, key_fix, key_hop);
|
||||
}
|
||||
instance ->common.serial= key_fix&0x0FFFFF;
|
||||
instance->common.btn = key_fix >> 28;
|
||||
if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
|
||||
}
|
||||
|
||||
/** Send bit
|
||||
*
|
||||
* @param instance - SubGhzProtocolKeeloq instance
|
||||
* @param bit - bit
|
||||
*/
|
||||
void subghz_protocol_keeloq_send_bit(SubGhzProtocolKeeloq* instance, uint8_t bit) {
|
||||
if (bit) {
|
||||
// send bit 1
|
||||
|
@ -297,8 +315,6 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, LevelPair data
|
|||
//ToDo out data display
|
||||
subghz_protocol_keeloq_check_remote_controller(instance);
|
||||
|
||||
//Print_Code(&KEELOQ);
|
||||
//Reverse_Code(KEELOQ.Code);
|
||||
instance->common.code_found = 0;
|
||||
instance->common.code_count_bit = 0;
|
||||
instance->common.header_count = 0;
|
||||
|
@ -329,7 +345,6 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, LevelPair data
|
|||
}
|
||||
|
||||
void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t output) {
|
||||
//snprintf(BufTX, sizeof(BufTX),"Protocol %s: %d Bit | KEY:0x%llX HEX \n\r", common->Name_Protocol, common->Count_BIT, common->Code);
|
||||
uint32_t code_found_hi = instance->common.code_found >> 32;
|
||||
uint32_t code_found_lo = instance->common.code_found & 0x00000000ffffffff;
|
||||
|
||||
|
@ -337,42 +352,26 @@ void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t outp
|
|||
|
||||
uint32_t code_found_reverse_hi = code_found_reverse>>32;
|
||||
uint32_t code_found_reverse_lo = code_found_reverse&0x00000000ffffffff;
|
||||
|
||||
if (code_found_hi>0) {
|
||||
string_cat_printf(
|
||||
output,
|
||||
"Protocol %s, %d Bit\r\n"
|
||||
" KEY:0x%lX%08lX\r\n"
|
||||
" YEK:0x%lX%08lX\r\n",
|
||||
"KEY:0x%lX%lX\r\n"
|
||||
"FIX:%lX MF:%s \r\n"
|
||||
"HOP:%lX \r\n"
|
||||
//"CNT:%04X BTN:%02lX\r\n",
|
||||
"SN:%05lX CNT:%04X BTN:%02lX\r\n",
|
||||
//"YEK:0x%lX%lX\r\n",
|
||||
instance->common.name,
|
||||
instance->common.code_count_bit,
|
||||
code_found_hi,
|
||||
code_found_lo,
|
||||
//code_found_reverse_hi,
|
||||
//code_found_reverse_lo
|
||||
code_found_reverse_hi,
|
||||
code_found_reverse_lo
|
||||
);
|
||||
} else {
|
||||
string_cat_printf(
|
||||
output,
|
||||
"Protocol %s, %d Bit\r\n"
|
||||
" KEY:0x%lX%lX\r\n"
|
||||
" YEK:0x%lX%lX\r\n",
|
||||
instance->common.name,
|
||||
instance->common.code_count_bit,
|
||||
code_found_hi,
|
||||
code_found_lo,
|
||||
code_found_reverse_hi,
|
||||
code_found_reverse_lo
|
||||
);
|
||||
}
|
||||
string_cat_printf(
|
||||
output,
|
||||
" MF:%s FIX:%lX\r\n"
|
||||
" HOP:%lX CNT:%04X BTN:%02lX\r\n",
|
||||
instance->manufacture_name,
|
||||
code_found_reverse_hi,
|
||||
code_found_reverse_lo,
|
||||
instance->common.cnt, //need manufacture code
|
||||
code_found_reverse_hi >> 28
|
||||
instance->common.serial,
|
||||
instance->common.cnt,
|
||||
instance->common.btn
|
||||
);
|
||||
}
|
|
@ -4,14 +4,46 @@
|
|||
|
||||
typedef struct SubGhzProtocolKeeloq SubGhzProtocolKeeloq;
|
||||
|
||||
/** Allocate SubGhzProtocolKeeloq
|
||||
*
|
||||
* @return SubGhzProtocolKeeloq*
|
||||
*/
|
||||
SubGhzProtocolKeeloq* subghz_protocol_keeloq_alloc();
|
||||
|
||||
/** Free SubGhzProtocolKeeloq
|
||||
*
|
||||
* @param instance
|
||||
*/
|
||||
void subghz_protocol_keeloq_free(SubGhzProtocolKeeloq* instance);
|
||||
|
||||
/** Loading of manufacture keys
|
||||
*
|
||||
* @param instance - SubGhzProtocolKeeloq instance
|
||||
* @param name - key name
|
||||
* @param key - manufacture (64bit)
|
||||
* @param type - type manufacture key
|
||||
*/
|
||||
void subghz_protocol_keeloq_add_manafacture_key(SubGhzProtocolKeeloq* instance, const char* name, uint64_t key, uint16_t type);
|
||||
|
||||
/** Sends the key on the air
|
||||
*
|
||||
* @param instance - SubGhzProtocolKeeloq instance
|
||||
* @param key - key send
|
||||
* @param bit - count bit key
|
||||
* @param repeat - repeat send key
|
||||
*/
|
||||
void subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, uint64_t key, uint8_t bit, uint8_t repeat);
|
||||
|
||||
/** Parse accepted duration
|
||||
*
|
||||
* @param instance - SubGhzProtocolKeeloq instance
|
||||
* @param data - LevelPair data
|
||||
*/
|
||||
void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, LevelPair data);
|
||||
|
||||
/** Outputting information from the parser
|
||||
*
|
||||
* @param instance - SubGhzProtocolKeeloq* instance
|
||||
* @param output - output string
|
||||
*/
|
||||
void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t output);
|
||||
|
|
|
@ -27,6 +27,11 @@ void subghz_protocol_nice_flo_free(SubGhzProtocolNiceFlo* instance) {
|
|||
free(instance);
|
||||
}
|
||||
|
||||
/** Send bit
|
||||
*
|
||||
* @param instance - SubGhzProtocolNiceFlo instance
|
||||
* @param bit - bit
|
||||
*/
|
||||
void subghz_protocol_nice_flo_send_bit(SubGhzProtocolNiceFlo* instance, uint8_t bit) {
|
||||
if (bit) {
|
||||
//send bit 1
|
||||
|
@ -87,6 +92,7 @@ void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, LevelPair d
|
|||
if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
|
||||
|
||||
//ToDo out data display
|
||||
//instance->common.serial = 0x12345;
|
||||
if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -4,12 +4,30 @@
|
|||
|
||||
typedef struct SubGhzProtocolNiceFlo SubGhzProtocolNiceFlo;
|
||||
|
||||
/** Allocate SubGhzProtocolNiceFlo
|
||||
*
|
||||
* @return SubGhzProtocolNiceFlo*
|
||||
*/
|
||||
SubGhzProtocolNiceFlo* subghz_protocol_nice_flo_alloc();
|
||||
|
||||
/** Free SubGhzProtocolNiceFlo
|
||||
*
|
||||
* @param instance
|
||||
*/
|
||||
void subghz_protocol_nice_flo_free(SubGhzProtocolNiceFlo* instance);
|
||||
|
||||
void subghz_protocol_nice_flo_set_callback(SubGhzProtocolNiceFlo* instance, SubGhzProtocolCommonCallback callback, void* context);
|
||||
|
||||
/** Sends the key on the air
|
||||
*
|
||||
* @param instance - SubGhzProtocolNiceFlo instance
|
||||
* @param key - key send
|
||||
* @param bit - count bit key
|
||||
* @param repeat - repeat send key
|
||||
*/
|
||||
void subghz_protocol_nice_flo_send_key(SubGhzProtocolNiceFlo* instance, uint64_t key, uint8_t bit, uint8_t repeat);
|
||||
|
||||
/** Parse accepted duration
|
||||
*
|
||||
* @param instance - SubGhzProtocolNiceFlo instance
|
||||
* @param data - LevelPair data
|
||||
*/
|
||||
void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, LevelPair data);
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#include "subghz_protocol_nice_flor_s.h"
|
||||
|
||||
#include <furi.h>
|
||||
#include "file-worker.h"
|
||||
/*
|
||||
* https://phreakerclub.com/1615
|
||||
* https://phreakerclub.com/forum/showthread.php?t=2360
|
||||
|
@ -7,16 +10,18 @@
|
|||
|
||||
struct SubGhzProtocolNiceFlorS {
|
||||
SubGhzProtocolCommon common;
|
||||
const char* rainbow_table_file_name;
|
||||
};
|
||||
|
||||
SubGhzProtocolNiceFlorS* subghz_protocol_nice_flor_s_alloc() {
|
||||
SubGhzProtocolNiceFlorS* instance = furi_alloc(sizeof(SubGhzProtocolNiceFlorS));
|
||||
|
||||
instance->common.name = "Nice FloR S";
|
||||
instance->common.name = "Nice FloR-S";
|
||||
instance->common.code_min_count_bit_for_found = 52;
|
||||
instance->common.te_shot = 500;
|
||||
instance->common.te_long = 1000;
|
||||
instance->common.te_delta = 300;
|
||||
instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nice_flor_s_to_str;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
@ -26,8 +31,18 @@ void subghz_protocol_nice_flor_s_free(SubGhzProtocolNiceFlorS* instance) {
|
|||
free(instance);
|
||||
}
|
||||
|
||||
void subghz_protocol_nice_flor_s_name_file(SubGhzProtocolNiceFlorS* instance, const char* name) {
|
||||
instance->rainbow_table_file_name = name;
|
||||
printf("Loading Nice FloR S rainbow table %s\r\n", name);
|
||||
}
|
||||
|
||||
/** Send bit
|
||||
*
|
||||
* @param instance - SubGhzProtocolNiceFlorS instance
|
||||
* @param bit - bit
|
||||
*/
|
||||
void subghz_protocol_nice_flor_s_send_bit(SubGhzProtocolNiceFlorS* instance, uint8_t bit) {
|
||||
if (bit) {
|
||||
if(bit) {
|
||||
//send bit 1
|
||||
SUBGHZ_TX_PIN_HIGTH();
|
||||
delay_us(instance->common.te_long);
|
||||
|
@ -42,33 +57,98 @@ void subghz_protocol_nice_flor_s_send_bit(SubGhzProtocolNiceFlorS* instance, uin
|
|||
}
|
||||
}
|
||||
|
||||
void subghz_protocol_nice_flor_s_send_key(SubGhzProtocolNiceFlorS* instance, uint64_t key, uint8_t bit, uint8_t repeat) {
|
||||
while (repeat--) {
|
||||
void subghz_protocol_nice_flor_s_send_key(
|
||||
SubGhzProtocolNiceFlorS* instance,
|
||||
uint64_t key,
|
||||
uint8_t bit,
|
||||
uint8_t repeat) {
|
||||
while(repeat--) {
|
||||
//Send header
|
||||
SUBGHZ_TX_PIN_LOW();
|
||||
delay_us(instance->common.te_shot * 34);
|
||||
//Send Start Bit
|
||||
SUBGHZ_TX_PIN_HIGTH();
|
||||
delay_us(instance->common.te_shot*3);
|
||||
delay_us(instance->common.te_shot * 3);
|
||||
SUBGHZ_TX_PIN_LOW();
|
||||
delay_us(instance->common.te_shot*3);
|
||||
delay_us(instance->common.te_shot * 3);
|
||||
//Send key data
|
||||
for (uint8_t i = bit; i > 0; i--) {
|
||||
for(uint8_t i = bit; i > 0; i--) {
|
||||
subghz_protocol_nice_flor_s_send_bit(instance, bit_read(key, i - 1));
|
||||
}
|
||||
//Send Stop Bit
|
||||
SUBGHZ_TX_PIN_HIGTH();
|
||||
delay_us(instance->common.te_shot*3);
|
||||
delay_us(instance->common.te_shot * 3);
|
||||
SUBGHZ_TX_PIN_LOW();
|
||||
delay_us(instance->common.te_shot*3);
|
||||
delay_us(instance->common.te_shot * 3);
|
||||
}
|
||||
}
|
||||
|
||||
/** Read bytes from rainbow table
|
||||
*
|
||||
* @param instance - SubGhzProtocolNiceFlorS* instance
|
||||
* @param address - address byte
|
||||
* @return byte data
|
||||
*/
|
||||
uint8_t subghz_nice_flor_s_get_byte_in_file(SubGhzProtocolNiceFlorS* instance, uint32_t address) {
|
||||
if(!instance->rainbow_table_file_name)
|
||||
return 0;
|
||||
|
||||
uint8_t buffer = 0;
|
||||
FileWorker* file_worker = file_worker_alloc(true);
|
||||
if(file_worker_open(file_worker, instance->rainbow_table_file_name, FSAM_READ, FSOM_OPEN_EXISTING)) {
|
||||
file_worker_seek(file_worker, address, true);
|
||||
file_worker_read(file_worker, &buffer, 1);
|
||||
// bool res = file_worker_read(file_worker, &buffer, 1);
|
||||
// furi_assert(res== true);
|
||||
}
|
||||
file_worker_close(file_worker);
|
||||
file_worker_free(file_worker);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/** Decrypt protocol Nice Flor S
|
||||
*
|
||||
* @param instance - SubGhzProtocolNiceFlorS* instance
|
||||
*/
|
||||
void subghz_nice_flor_s_decoder_decrypt(SubGhzProtocolNiceFlorS* instance) {
|
||||
/*
|
||||
* Packet format Nice Flor-s: START-P0-P1-P2-P3-P4-P5-P6-P7-STOP
|
||||
* P0 (4-bit) - button positional code - 1:0x1, 2:0x2, 3:0x4, 4:0x8;
|
||||
* P1 (4-bit) - batch repetition number, calculated by the formula:
|
||||
* P1 = 0xF ^ P0 ^ n; where n changes from 1 to 15, then 0, and then in a circle
|
||||
* key 1: {0xF,0xC,0xD,0xA,0xB,0x8,0x9,0x6,0x7,0x4,0x5,0x2,0x3,0x0,0x1,0xE};
|
||||
* key 2: {0xC,0xF,0xE,0x9,0x8,0xB,0xA,0x5,0x4,0x7,0x6,0x1,0x0,0x3,0x2,0xD};
|
||||
* key 3: {0xA,0x9,0x8,0xF,0xE,0xD,0xC,0x3,0x2,0x1,0x0,0x7,0x6,0x5,0x4,0xB};
|
||||
* P2 (4-bit) - part of the serial number, P2 = (K ^ S3) & 0xF;
|
||||
* P3 (byte) - the major part of the encrypted index
|
||||
* P4 (byte) - the low-order part of the encrypted index
|
||||
* P5 (byte) - part of the serial number, P5 = K ^ S2;
|
||||
* P6 (byte) - part of the serial number, P6 = K ^ S1;
|
||||
* P7 (byte) - part of the serial number, P7 = K ^ S0;
|
||||
* K (byte) - depends on P3 and P4, K = Fk(P3, P4);
|
||||
* S3,S2,S1,S0 - serial number of the console 28 bit.
|
||||
*/
|
||||
|
||||
uint16_t p3p4 = (uint16_t)(instance->common.code_found >> 24);
|
||||
instance->common.cnt = subghz_nice_flor_s_get_byte_in_file(instance,p3p4*2) << 8 | subghz_nice_flor_s_get_byte_in_file(instance,p3p4*2+1); //nice_flor_srainbow_table_for_search[p3p4]; тут надо считать поле с файла причем адрес надо у множить на 2
|
||||
uint8_t k =(uint8_t)(p3p4 & 0x00FF) ^subghz_nice_flor_s_get_byte_in_file(instance,(0x20000 |(instance->common.cnt &0x00ff))); //nice_flor_srainbow_table_for_search[0x10000|subghz_protocol_nice_flor_s.cnt & 0x00ff];
|
||||
|
||||
uint8_t s3 = ((uint8_t)(instance->common.code_found >> 40) ^ k) & 0x0f;
|
||||
uint8_t s2 = ((uint8_t)(instance->common.code_found >> 16) ^ k);
|
||||
uint8_t s1 = ((uint8_t)(instance->common.code_found >> 8) ^ k);
|
||||
uint8_t s0 = ((uint8_t)(instance->common.code_found) ^ k);
|
||||
instance->common.serial = s3 << 24 | s2 << 16 | s1 << 8 | s0;
|
||||
|
||||
instance->common.btn = (instance->common.code_found >> 48) & 0x0f;
|
||||
if(instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
|
||||
}
|
||||
|
||||
void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelPair data) {
|
||||
switch (instance->common.parser_step) {
|
||||
switch(instance->common.parser_step) {
|
||||
case 0:
|
||||
if ((data.level == ApiHalSubGhzCaptureLevelLow)
|
||||
&& (DURATION_DIFF(data.duration,instance->common.te_shot * 38)< instance->common.te_delta * 38)) {
|
||||
if((data.level == ApiHalSubGhzCaptureLevelLow)
|
||||
&& (DURATION_DIFF(data.duration, instance->common.te_shot * 38) < instance->common.te_delta * 38)) {
|
||||
//Found start header Nice Flor-S
|
||||
instance->common.parser_step = 1;
|
||||
} else {
|
||||
|
@ -76,8 +156,8 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelP
|
|||
}
|
||||
break;
|
||||
case 1:
|
||||
if ((data.level == ApiHalSubGhzCaptureLevelHigh)
|
||||
&& (DURATION_DIFF(data.duration,instance->common.te_shot * 3)< instance->common.te_delta * 3)) {
|
||||
if((data.level == ApiHalSubGhzCaptureLevelHigh)
|
||||
&& (DURATION_DIFF(data.duration, instance->common.te_shot * 3) < instance->common.te_delta * 3)) {
|
||||
//Found next header Nice Flor-S
|
||||
instance->common.parser_step = 2;
|
||||
} else {
|
||||
|
@ -85,8 +165,8 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelP
|
|||
}
|
||||
break;
|
||||
case 2:
|
||||
if ((data.level == ApiHalSubGhzCaptureLevelLow)
|
||||
&& (DURATION_DIFF(data.duration,instance->common.te_shot * 3)< instance->common.te_delta * 3)) {
|
||||
if((data.level == ApiHalSubGhzCaptureLevelLow)
|
||||
&& (DURATION_DIFF(data.duration, instance->common.te_shot * 3) < instance->common.te_delta * 3)) {
|
||||
//Found header Nice Flor-S
|
||||
instance->common.parser_step = 3;
|
||||
instance->common.code_found = 0;
|
||||
|
@ -96,14 +176,13 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelP
|
|||
}
|
||||
break;
|
||||
case 3:
|
||||
if (data.level == ApiHalSubGhzCaptureLevelHigh) {
|
||||
if(DURATION_DIFF(data.duration,instance->common.te_shot*3) < instance->common.te_delta){
|
||||
if(data.level == ApiHalSubGhzCaptureLevelHigh) {
|
||||
if(DURATION_DIFF(data.duration, instance->common.te_shot * 3) < instance->common.te_delta) {
|
||||
//Found STOP bit
|
||||
instance->common.parser_step = 0;
|
||||
if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
|
||||
|
||||
if(instance->common.code_count_bit >=instance->common.code_min_count_bit_for_found) {
|
||||
//ToDo out data display
|
||||
if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
|
||||
subghz_nice_flor_s_decoder_decrypt(instance);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
|
@ -114,13 +193,14 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelP
|
|||
}
|
||||
break;
|
||||
case 4:
|
||||
if (data.level == ApiHalSubGhzCaptureLevelLow) {
|
||||
if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot) < instance->common.te_delta)
|
||||
&& (DURATION_DIFF(data.duration,instance->common.te_long)< instance->common.te_delta)) {
|
||||
if(data.level == ApiHalSubGhzCaptureLevelLow) {
|
||||
if((DURATION_DIFF(instance->common.te_last, instance->common.te_shot) < instance->common.te_delta)
|
||||
&&(DURATION_DIFF(data.duration, instance->common.te_long) < instance->common.te_delta)) {
|
||||
subghz_protocol_common_add_bit(&instance->common, 0);
|
||||
instance->common.parser_step = 3;
|
||||
} else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long)< instance->common.te_delta)
|
||||
&& (DURATION_DIFF(data.duration,instance->common.te_shot)< instance->common.te_delta)) {
|
||||
} else if(
|
||||
(DURATION_DIFF(instance->common.te_last, instance->common.te_long) < instance->common.te_delta)
|
||||
&&(DURATION_DIFF(data.duration, instance->common.te_shot) < instance->common.te_delta)) {
|
||||
subghz_protocol_common_add_bit(&instance->common, 1);
|
||||
instance->common.parser_step = 3;
|
||||
} else
|
||||
|
@ -131,3 +211,23 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelP
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void subghz_protocol_nice_flor_s_to_str(SubGhzProtocolNiceFlorS* instance, string_t output) {
|
||||
uint32_t code_found_hi = instance->common.code_found >> 32;
|
||||
uint32_t code_found_lo = instance->common.code_found & 0x00000000ffffffff;
|
||||
|
||||
string_cat_printf(
|
||||
output,
|
||||
"Protocol %s, %d Bit\r\n"
|
||||
" KEY:0x%lX%08lX\r\n"
|
||||
" SN:%05lX\r\n"
|
||||
" CNT:%04X BTN:%02lX\r\n",
|
||||
instance->common.name,
|
||||
instance->common.code_count_bit,
|
||||
code_found_hi,
|
||||
code_found_lo,
|
||||
instance->common.serial,
|
||||
instance->common.cnt,
|
||||
instance->common.btn
|
||||
);
|
||||
}
|
|
@ -4,12 +4,44 @@
|
|||
|
||||
typedef struct SubGhzProtocolNiceFlorS SubGhzProtocolNiceFlorS;
|
||||
|
||||
/** Allocate SubGhzProtocolNiceFlorS
|
||||
*
|
||||
* @return SubGhzProtocolNiceFlorS*
|
||||
*/
|
||||
SubGhzProtocolNiceFlorS* subghz_protocol_nice_flor_s_alloc();
|
||||
|
||||
/** Free SubGhzProtocolNiceFlorS
|
||||
*
|
||||
* @param instance
|
||||
*/
|
||||
void subghz_protocol_nice_flor_s_free(SubGhzProtocolNiceFlorS* instance);
|
||||
|
||||
void subghz_protocol_nice_flor_s_set_callback(SubGhzProtocolNiceFlorS* instance, SubGhzProtocolCommonCallback callback, void* context);
|
||||
/** File name rainbow table Nice Flor-S
|
||||
*
|
||||
* @param instance - SubGhzProtocolNiceFlorS instance
|
||||
* @param file_name - "path/file_name"
|
||||
*/
|
||||
void subghz_protocol_nice_flor_s_name_file(SubGhzProtocolNiceFlorS* instance, const char* name);
|
||||
|
||||
/** Sends the key on the air
|
||||
*
|
||||
* @param instance - SubGhzProtocolNiceFlorS instance
|
||||
* @param key - key send
|
||||
* @param bit - count bit key
|
||||
* @param repeat - repeat send key
|
||||
*/
|
||||
void subghz_protocol_nice_flor_s_send_key(SubGhzProtocolNiceFlorS* instance, uint64_t key, uint8_t bit, uint8_t repeat);
|
||||
|
||||
/** Parse accepted duration
|
||||
*
|
||||
* @param instance - SubGhzProtocolNiceFlorS instance
|
||||
* @param data - LevelPair data
|
||||
*/
|
||||
void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelPair data);
|
||||
|
||||
/** Outputting information from the parser
|
||||
*
|
||||
* @param instance - SubGhzProtocolNiceFlorS* instance
|
||||
* @param output - output string
|
||||
*/
|
||||
void subghz_protocol_nice_flor_s_to_str(SubGhzProtocolNiceFlorS* instance, string_t output);
|
||||
|
|
|
@ -27,6 +27,11 @@ void subghz_protocol_princeton_free(SubGhzProtocolPrinceton* instance) {
|
|||
free(instance);
|
||||
}
|
||||
|
||||
/** Send bit
|
||||
*
|
||||
* @param instance - SubGhzProtocolPrinceton instance
|
||||
* @param bit - bit
|
||||
*/
|
||||
void subghz_protocol_princeton_send_bit(SubGhzProtocolPrinceton* instance, uint8_t bit) {
|
||||
if (bit) {
|
||||
//send bit 1
|
||||
|
@ -83,6 +88,8 @@ void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, LevelPai
|
|||
instance->common.parser_step = 1;
|
||||
if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
|
||||
//ToDo out data display
|
||||
instance->common.serial = instance->common.code_found >> 4;
|
||||
instance->common.btn = (uint8_t)instance->common.code_found & 0x00000F;
|
||||
if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
|
||||
}
|
||||
instance->common.code_found = 0;
|
||||
|
|
|
@ -4,12 +4,37 @@
|
|||
|
||||
typedef struct SubGhzProtocolPrinceton SubGhzProtocolPrinceton;
|
||||
|
||||
/** Allocate SubGhzProtocolPrinceton
|
||||
*
|
||||
* @return SubGhzProtocolPrinceton*
|
||||
*/
|
||||
SubGhzProtocolPrinceton* subghz_protocol_princeton_alloc();
|
||||
|
||||
/** Free SubGhzProtocolPrinceton
|
||||
*
|
||||
* @param instance
|
||||
*/
|
||||
void subghz_protocol_princeton_free(SubGhzProtocolPrinceton* instance);
|
||||
|
||||
/** Sends the key on the air
|
||||
*
|
||||
* @param instance - SubGhzProtocolPrinceton instance
|
||||
* @param key - key send
|
||||
* @param bit - count bit key
|
||||
* @param repeat - repeat send key
|
||||
*/
|
||||
void subghz_protocol_princeton_send_key(SubGhzProtocolPrinceton* instance, uint64_t key, uint8_t bit, uint8_t repeat);
|
||||
|
||||
/** Parse accepted duration
|
||||
*
|
||||
* @param instance - SubGhzProtocolPrinceton instance
|
||||
* @param data - LevelPair data
|
||||
*/
|
||||
void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, LevelPair data);
|
||||
|
||||
void subghz_protocol_princeton_to_str(SubGhzProtocolPrinceton* instance, string_t output);
|
||||
/** Outputting information from the parser
|
||||
*
|
||||
* @param instance - SubGhzProtocolPrinceton* instance
|
||||
* @param output - output string
|
||||
*/
|
||||
//void subghz_protocol_princeton_to_str(SubGhzProtocolPrinceton* instance, string_t output);
|
||||
|
|
|
@ -15,6 +15,12 @@ struct SubGhzWorker {
|
|||
void* context;
|
||||
};
|
||||
|
||||
/** Rx callback timer
|
||||
*
|
||||
* @param level received signal level
|
||||
* @param duration received signal duration
|
||||
* @param context
|
||||
*/
|
||||
void subghz_worker_rx_callback(
|
||||
ApiHalSubGhzCaptureLevel level,
|
||||
uint32_t duration,
|
||||
|
@ -34,6 +40,11 @@ void subghz_worker_rx_callback(
|
|||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
/** Worker callback thread
|
||||
*
|
||||
* @param context
|
||||
* @return exit code
|
||||
*/
|
||||
static int32_t subghz_worker_thread_callback(void* context) {
|
||||
SubGhzWorker* instance = context;
|
||||
|
||||
|
|
|
@ -10,16 +10,47 @@ typedef void (*SubGhzWorkerPairCallback)(void* context, LevelPair pair);
|
|||
|
||||
void subghz_worker_rx_callback(ApiHalSubGhzCaptureLevel level, uint32_t duration, void* context);
|
||||
|
||||
/** Allocate SubGhzWorker
|
||||
*
|
||||
* @return SubGhzWorker*
|
||||
*/
|
||||
SubGhzWorker* subghz_worker_alloc();
|
||||
|
||||
/** Free SubGhzWorker
|
||||
*
|
||||
* @param instance SubGhzWorker instance
|
||||
*/
|
||||
void subghz_worker_free(SubGhzWorker* instance);
|
||||
|
||||
/** Overrun callback SubGhzWorker
|
||||
*
|
||||
* @param instance SubGhzWorker instance
|
||||
* @param callback SubGhzWorkerOverrunCallback callback
|
||||
*/
|
||||
void subghz_worker_set_overrun_callback(SubGhzWorker* instance, SubGhzWorkerOverrunCallback callback);
|
||||
|
||||
/** Pair callback SubGhzWorker
|
||||
*
|
||||
* @param instance SubGhzWorker instance
|
||||
* @param callback SubGhzWorkerOverrunCallback callback
|
||||
*/
|
||||
void subghz_worker_set_pair_callback(SubGhzWorker* instance, SubGhzWorkerPairCallback callback);
|
||||
|
||||
/** Context callback SubGhzWorker
|
||||
*
|
||||
* @param instance SubGhzWorker instance
|
||||
* @param context
|
||||
*/
|
||||
void subghz_worker_set_context(SubGhzWorker* instance, void* context);
|
||||
|
||||
/** Start SubGhzWorker
|
||||
*
|
||||
* @param instance SubGhzWorker instance
|
||||
*/
|
||||
void subghz_worker_start(SubGhzWorker* instance);
|
||||
|
||||
/** Stop SubGhzWorker
|
||||
*
|
||||
* @param instance SubGhzWorker instance
|
||||
*/
|
||||
void subghz_worker_stop(SubGhzWorker* instance);
|
||||
|
|
Loading…
Reference in a new issue