mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-22 05:14:46 -07:00
Fixed Infrared FAP when fixing Infrared CLI
This commit is contained in:
@@ -16,11 +16,3 @@ App(
|
|||||||
fap_icon="ir_10px.png",
|
fap_icon="ir_10px.png",
|
||||||
fap_icon_assets="images",
|
fap_icon_assets="images",
|
||||||
)
|
)
|
||||||
|
|
||||||
App(
|
|
||||||
appid="infrared_start",
|
|
||||||
apptype=FlipperAppType.STARTUP,
|
|
||||||
entry_point="infrared_on_system_start",
|
|
||||||
requires=["infrared"],
|
|
||||||
order=20,
|
|
||||||
)
|
|
||||||
|
|||||||
158
applications/main/infrared/infrared_brute_force.c
Normal file
158
applications/main/infrared/infrared_brute_force.c
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
#include "infrared_brute_force.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <m-dict.h>
|
||||||
|
#include <flipper_format/flipper_format.h>
|
||||||
|
|
||||||
|
#include "infrared_signal.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t index;
|
||||||
|
uint32_t count;
|
||||||
|
} InfraredBruteForceRecord;
|
||||||
|
|
||||||
|
DICT_DEF2(
|
||||||
|
InfraredBruteForceRecordDict,
|
||||||
|
FuriString*,
|
||||||
|
FURI_STRING_OPLIST,
|
||||||
|
InfraredBruteForceRecord,
|
||||||
|
M_POD_OPLIST);
|
||||||
|
|
||||||
|
struct InfraredBruteForce {
|
||||||
|
FlipperFormat* ff;
|
||||||
|
const char* db_filename;
|
||||||
|
FuriString* current_record_name;
|
||||||
|
InfraredSignal* current_signal;
|
||||||
|
InfraredBruteForceRecordDict_t records;
|
||||||
|
bool is_started;
|
||||||
|
};
|
||||||
|
|
||||||
|
InfraredBruteForce* infrared_brute_force_alloc() {
|
||||||
|
InfraredBruteForce* brute_force = malloc(sizeof(InfraredBruteForce));
|
||||||
|
brute_force->ff = NULL;
|
||||||
|
brute_force->db_filename = NULL;
|
||||||
|
brute_force->current_signal = NULL;
|
||||||
|
brute_force->is_started = false;
|
||||||
|
brute_force->current_record_name = furi_string_alloc();
|
||||||
|
InfraredBruteForceRecordDict_init(brute_force->records);
|
||||||
|
return brute_force;
|
||||||
|
}
|
||||||
|
|
||||||
|
void infrared_brute_force_clear_records(InfraredBruteForce* brute_force) {
|
||||||
|
furi_assert(!brute_force->is_started);
|
||||||
|
InfraredBruteForceRecordDict_reset(brute_force->records);
|
||||||
|
}
|
||||||
|
|
||||||
|
void infrared_brute_force_free(InfraredBruteForce* brute_force) {
|
||||||
|
furi_assert(!brute_force->is_started);
|
||||||
|
InfraredBruteForceRecordDict_clear(brute_force->records);
|
||||||
|
furi_string_free(brute_force->current_record_name);
|
||||||
|
free(brute_force);
|
||||||
|
}
|
||||||
|
|
||||||
|
void infrared_brute_force_set_db_filename(InfraredBruteForce* brute_force, const char* db_filename) {
|
||||||
|
furi_assert(!brute_force->is_started);
|
||||||
|
brute_force->db_filename = db_filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool infrared_brute_force_calculate_messages(InfraredBruteForce* brute_force) {
|
||||||
|
furi_assert(!brute_force->is_started);
|
||||||
|
furi_assert(brute_force->db_filename);
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||||
|
FlipperFormat* ff = flipper_format_buffered_file_alloc(storage);
|
||||||
|
|
||||||
|
success = flipper_format_buffered_file_open_existing(ff, brute_force->db_filename);
|
||||||
|
if(success) {
|
||||||
|
FuriString* signal_name;
|
||||||
|
signal_name = furi_string_alloc();
|
||||||
|
while(flipper_format_read_string(ff, "name", signal_name)) {
|
||||||
|
InfraredBruteForceRecord* record =
|
||||||
|
InfraredBruteForceRecordDict_get(brute_force->records, signal_name);
|
||||||
|
if(record) {
|
||||||
|
++(record->count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
furi_string_free(signal_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
flipper_format_free(ff);
|
||||||
|
furi_record_close(RECORD_STORAGE);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool infrared_brute_force_start(
|
||||||
|
InfraredBruteForce* brute_force,
|
||||||
|
uint32_t index,
|
||||||
|
uint32_t* record_count) {
|
||||||
|
furi_assert(!brute_force->is_started);
|
||||||
|
bool success = false;
|
||||||
|
*record_count = 0;
|
||||||
|
|
||||||
|
InfraredBruteForceRecordDict_it_t it;
|
||||||
|
for(InfraredBruteForceRecordDict_it(it, brute_force->records);
|
||||||
|
!InfraredBruteForceRecordDict_end_p(it);
|
||||||
|
InfraredBruteForceRecordDict_next(it)) {
|
||||||
|
const InfraredBruteForceRecordDict_itref_t* record = InfraredBruteForceRecordDict_cref(it);
|
||||||
|
if(record->value.index == index) {
|
||||||
|
*record_count = record->value.count;
|
||||||
|
if(*record_count) {
|
||||||
|
furi_string_set(brute_force->current_record_name, record->key);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*record_count) {
|
||||||
|
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||||
|
brute_force->ff = flipper_format_buffered_file_alloc(storage);
|
||||||
|
brute_force->current_signal = infrared_signal_alloc();
|
||||||
|
brute_force->is_started = true;
|
||||||
|
success =
|
||||||
|
flipper_format_buffered_file_open_existing(brute_force->ff, brute_force->db_filename);
|
||||||
|
if(!success) infrared_brute_force_stop(brute_force);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool infrared_brute_force_is_started(InfraredBruteForce* brute_force) {
|
||||||
|
return brute_force->is_started;
|
||||||
|
}
|
||||||
|
|
||||||
|
void infrared_brute_force_stop(InfraredBruteForce* brute_force) {
|
||||||
|
furi_assert(brute_force->is_started);
|
||||||
|
furi_string_reset(brute_force->current_record_name);
|
||||||
|
infrared_signal_free(brute_force->current_signal);
|
||||||
|
flipper_format_free(brute_force->ff);
|
||||||
|
brute_force->current_signal = NULL;
|
||||||
|
brute_force->ff = NULL;
|
||||||
|
brute_force->is_started = false;
|
||||||
|
furi_record_close(RECORD_STORAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool infrared_brute_force_send_next(InfraredBruteForce* brute_force) {
|
||||||
|
furi_assert(brute_force->is_started);
|
||||||
|
const bool success = infrared_signal_search_and_read(
|
||||||
|
brute_force->current_signal, brute_force->ff, brute_force->current_record_name);
|
||||||
|
if(success) {
|
||||||
|
infrared_signal_transmit(brute_force->current_signal);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
void infrared_brute_force_add_record(
|
||||||
|
InfraredBruteForce* brute_force,
|
||||||
|
uint32_t index,
|
||||||
|
const char* name) {
|
||||||
|
InfraredBruteForceRecord value = {.index = index, .count = 0};
|
||||||
|
FuriString* key;
|
||||||
|
key = furi_string_alloc_set(name);
|
||||||
|
InfraredBruteForceRecordDict_set_at(brute_force->records, key, value);
|
||||||
|
furi_string_free(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void infrared_brute_force_reset(InfraredBruteForce* brute_force) {
|
||||||
|
furi_assert(!brute_force->is_started);
|
||||||
|
InfraredBruteForceRecordDict_reset(brute_force->records);
|
||||||
|
}
|
||||||
23
applications/main/infrared/infrared_brute_force.h
Normal file
23
applications/main/infrared/infrared_brute_force.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct InfraredBruteForce InfraredBruteForce;
|
||||||
|
|
||||||
|
InfraredBruteForce* infrared_brute_force_alloc();
|
||||||
|
void infrared_brute_force_free(InfraredBruteForce* brute_force);
|
||||||
|
void infrared_brute_force_set_db_filename(InfraredBruteForce* brute_force, const char* db_filename);
|
||||||
|
bool infrared_brute_force_calculate_messages(InfraredBruteForce* brute_force);
|
||||||
|
bool infrared_brute_force_start(
|
||||||
|
InfraredBruteForce* brute_force,
|
||||||
|
uint32_t index,
|
||||||
|
uint32_t* record_count);
|
||||||
|
bool infrared_brute_force_is_started(InfraredBruteForce* brute_force);
|
||||||
|
void infrared_brute_force_stop(InfraredBruteForce* brute_force);
|
||||||
|
bool infrared_brute_force_send_next(InfraredBruteForce* brute_force);
|
||||||
|
void infrared_brute_force_clear_records(InfraredBruteForce* brute_force);
|
||||||
|
void infrared_brute_force_add_record(
|
||||||
|
InfraredBruteForce* brute_force,
|
||||||
|
uint32_t index,
|
||||||
|
const char* name);
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "infrared.h"
|
#include "infrared.h"
|
||||||
#include "infrared_remote.h"
|
#include "infrared_remote.h"
|
||||||
#include "../../services/infraredsrv/infrared_brute_force.h"
|
#include "infrared_brute_force.h"
|
||||||
#include "infrared_custom_event.h"
|
#include "infrared_custom_event.h"
|
||||||
|
|
||||||
#include "scenes/infrared_scene.h"
|
#include "scenes/infrared_scene.h"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../../services/infraredsrv/infrared_signal.h"
|
#include "infrared_signal.h"
|
||||||
|
|
||||||
typedef struct InfraredRemoteButton InfraredRemoteButton;
|
typedef struct InfraredRemoteButton InfraredRemoteButton;
|
||||||
|
|
||||||
|
|||||||
300
applications/main/infrared/infrared_signal.c
Normal file
300
applications/main/infrared/infrared_signal.c
Normal file
@@ -0,0 +1,300 @@
|
|||||||
|
#include "infrared_signal.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <core/check.h>
|
||||||
|
#include <infrared_worker.h>
|
||||||
|
#include <infrared_transmit.h>
|
||||||
|
|
||||||
|
#define TAG "InfraredSignal"
|
||||||
|
|
||||||
|
struct InfraredSignal {
|
||||||
|
bool is_raw;
|
||||||
|
union {
|
||||||
|
InfraredMessage message;
|
||||||
|
InfraredRawSignal raw;
|
||||||
|
} payload;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void infrared_signal_clear_timings(InfraredSignal* signal) {
|
||||||
|
if(signal->is_raw) {
|
||||||
|
free(signal->payload.raw.timings);
|
||||||
|
signal->payload.raw.timings_size = 0;
|
||||||
|
signal->payload.raw.timings = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool infrared_signal_is_message_valid(InfraredMessage* message) {
|
||||||
|
if(!infrared_is_protocol_valid(message->protocol)) {
|
||||||
|
FURI_LOG_E(TAG, "Unknown protocol");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t address_length = infrared_get_protocol_address_length(message->protocol);
|
||||||
|
uint32_t address_mask = (1UL << address_length) - 1;
|
||||||
|
|
||||||
|
if(message->address != (message->address & address_mask)) {
|
||||||
|
FURI_LOG_E(
|
||||||
|
TAG,
|
||||||
|
"Address is out of range (mask 0x%08lX): 0x%lX\r\n",
|
||||||
|
address_mask,
|
||||||
|
message->address);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t command_length = infrared_get_protocol_command_length(message->protocol);
|
||||||
|
uint32_t command_mask = (1UL << command_length) - 1;
|
||||||
|
|
||||||
|
if(message->command != (message->command & command_mask)) {
|
||||||
|
FURI_LOG_E(
|
||||||
|
TAG,
|
||||||
|
"Command is out of range (mask 0x%08lX): 0x%lX\r\n",
|
||||||
|
command_mask,
|
||||||
|
message->command);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool infrared_signal_is_raw_valid(InfraredRawSignal* raw) {
|
||||||
|
if((raw->frequency > INFRARED_MAX_FREQUENCY) || (raw->frequency < INFRARED_MIN_FREQUENCY)) {
|
||||||
|
FURI_LOG_E(
|
||||||
|
TAG,
|
||||||
|
"Frequency is out of range (%X - %X): %lX",
|
||||||
|
INFRARED_MIN_FREQUENCY,
|
||||||
|
INFRARED_MAX_FREQUENCY,
|
||||||
|
raw->frequency);
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} else if((raw->duty_cycle <= 0) || (raw->duty_cycle > 1)) {
|
||||||
|
FURI_LOG_E(TAG, "Duty cycle is out of range (0 - 1): %f", (double)raw->duty_cycle);
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} else if((raw->timings_size <= 0) || (raw->timings_size > MAX_TIMINGS_AMOUNT)) {
|
||||||
|
FURI_LOG_E(
|
||||||
|
TAG,
|
||||||
|
"Timings amount is out of range (0 - %X): %X",
|
||||||
|
MAX_TIMINGS_AMOUNT,
|
||||||
|
raw->timings_size);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool infrared_signal_save_message(InfraredMessage* message, FlipperFormat* ff) {
|
||||||
|
const char* protocol_name = infrared_get_protocol_name(message->protocol);
|
||||||
|
return flipper_format_write_string_cstr(ff, "type", "parsed") &&
|
||||||
|
flipper_format_write_string_cstr(ff, "protocol", protocol_name) &&
|
||||||
|
flipper_format_write_hex(ff, "address", (uint8_t*)&message->address, 4) &&
|
||||||
|
flipper_format_write_hex(ff, "command", (uint8_t*)&message->command, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool infrared_signal_save_raw(InfraredRawSignal* raw, FlipperFormat* ff) {
|
||||||
|
furi_assert(raw->timings_size <= MAX_TIMINGS_AMOUNT);
|
||||||
|
return flipper_format_write_string_cstr(ff, "type", "raw") &&
|
||||||
|
flipper_format_write_uint32(ff, "frequency", &raw->frequency, 1) &&
|
||||||
|
flipper_format_write_float(ff, "duty_cycle", &raw->duty_cycle, 1) &&
|
||||||
|
flipper_format_write_uint32(ff, "data", raw->timings, raw->timings_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool infrared_signal_read_message(InfraredSignal* signal, FlipperFormat* ff) {
|
||||||
|
FuriString* buf;
|
||||||
|
buf = furi_string_alloc();
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if(!flipper_format_read_string(ff, "protocol", buf)) break;
|
||||||
|
|
||||||
|
InfraredMessage message;
|
||||||
|
message.protocol = infrared_get_protocol_by_name(furi_string_get_cstr(buf));
|
||||||
|
|
||||||
|
success = flipper_format_read_hex(ff, "address", (uint8_t*)&message.address, 4) &&
|
||||||
|
flipper_format_read_hex(ff, "command", (uint8_t*)&message.command, 4) &&
|
||||||
|
infrared_signal_is_message_valid(&message);
|
||||||
|
|
||||||
|
if(!success) break;
|
||||||
|
|
||||||
|
infrared_signal_set_message(signal, &message);
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
furi_string_free(buf);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool infrared_signal_read_raw(InfraredSignal* signal, FlipperFormat* ff) {
|
||||||
|
uint32_t timings_size, frequency;
|
||||||
|
float duty_cycle;
|
||||||
|
|
||||||
|
bool success = flipper_format_read_uint32(ff, "frequency", &frequency, 1) &&
|
||||||
|
flipper_format_read_float(ff, "duty_cycle", &duty_cycle, 1) &&
|
||||||
|
flipper_format_get_value_count(ff, "data", &timings_size);
|
||||||
|
|
||||||
|
if(!success || timings_size > MAX_TIMINGS_AMOUNT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t* timings = malloc(sizeof(uint32_t) * timings_size);
|
||||||
|
success = flipper_format_read_uint32(ff, "data", timings, timings_size);
|
||||||
|
|
||||||
|
if(success) {
|
||||||
|
infrared_signal_set_raw_signal(signal, timings, timings_size, frequency, duty_cycle);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(timings);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool infrared_signal_read_body(InfraredSignal* signal, FlipperFormat* ff) {
|
||||||
|
FuriString* tmp = furi_string_alloc();
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if(!flipper_format_read_string(ff, "type", tmp)) break;
|
||||||
|
if(furi_string_equal(tmp, "raw")) {
|
||||||
|
success = infrared_signal_read_raw(signal, ff);
|
||||||
|
} else if(furi_string_equal(tmp, "parsed")) {
|
||||||
|
success = infrared_signal_read_message(signal, ff);
|
||||||
|
} else {
|
||||||
|
FURI_LOG_E(TAG, "Unknown signal type");
|
||||||
|
}
|
||||||
|
} while(false);
|
||||||
|
|
||||||
|
furi_string_free(tmp);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
InfraredSignal* infrared_signal_alloc() {
|
||||||
|
InfraredSignal* signal = malloc(sizeof(InfraredSignal));
|
||||||
|
|
||||||
|
signal->is_raw = false;
|
||||||
|
signal->payload.message.protocol = InfraredProtocolUnknown;
|
||||||
|
|
||||||
|
return signal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void infrared_signal_free(InfraredSignal* signal) {
|
||||||
|
infrared_signal_clear_timings(signal);
|
||||||
|
free(signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool infrared_signal_is_raw(InfraredSignal* signal) {
|
||||||
|
return signal->is_raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool infrared_signal_is_valid(InfraredSignal* signal) {
|
||||||
|
return signal->is_raw ? infrared_signal_is_raw_valid(&signal->payload.raw) :
|
||||||
|
infrared_signal_is_message_valid(&signal->payload.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void infrared_signal_set_signal(InfraredSignal* signal, const InfraredSignal* other) {
|
||||||
|
if(other->is_raw) {
|
||||||
|
const InfraredRawSignal* raw = &other->payload.raw;
|
||||||
|
infrared_signal_set_raw_signal(
|
||||||
|
signal, raw->timings, raw->timings_size, raw->frequency, raw->duty_cycle);
|
||||||
|
} else {
|
||||||
|
const InfraredMessage* message = &other->payload.message;
|
||||||
|
infrared_signal_set_message(signal, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void infrared_signal_set_raw_signal(
|
||||||
|
InfraredSignal* signal,
|
||||||
|
const uint32_t* timings,
|
||||||
|
size_t timings_size,
|
||||||
|
uint32_t frequency,
|
||||||
|
float duty_cycle) {
|
||||||
|
infrared_signal_clear_timings(signal);
|
||||||
|
|
||||||
|
signal->is_raw = true;
|
||||||
|
|
||||||
|
signal->payload.raw.timings_size = timings_size;
|
||||||
|
signal->payload.raw.frequency = frequency;
|
||||||
|
signal->payload.raw.duty_cycle = duty_cycle;
|
||||||
|
|
||||||
|
signal->payload.raw.timings = malloc(timings_size * sizeof(uint32_t));
|
||||||
|
memcpy(signal->payload.raw.timings, timings, timings_size * sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
InfraredRawSignal* infrared_signal_get_raw_signal(InfraredSignal* signal) {
|
||||||
|
furi_assert(signal->is_raw);
|
||||||
|
return &signal->payload.raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
void infrared_signal_set_message(InfraredSignal* signal, const InfraredMessage* message) {
|
||||||
|
infrared_signal_clear_timings(signal);
|
||||||
|
|
||||||
|
signal->is_raw = false;
|
||||||
|
signal->payload.message = *message;
|
||||||
|
}
|
||||||
|
|
||||||
|
InfraredMessage* infrared_signal_get_message(InfraredSignal* signal) {
|
||||||
|
furi_assert(!signal->is_raw);
|
||||||
|
return &signal->payload.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool infrared_signal_save(InfraredSignal* signal, FlipperFormat* ff, const char* name) {
|
||||||
|
if(!flipper_format_write_comment_cstr(ff, "") ||
|
||||||
|
!flipper_format_write_string_cstr(ff, "name", name)) {
|
||||||
|
return false;
|
||||||
|
} else if(signal->is_raw) {
|
||||||
|
return infrared_signal_save_raw(&signal->payload.raw, ff);
|
||||||
|
} else {
|
||||||
|
return infrared_signal_save_message(&signal->payload.message, ff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, FuriString* name) {
|
||||||
|
FuriString* tmp = furi_string_alloc();
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if(!flipper_format_read_string(ff, "name", tmp)) break;
|
||||||
|
furi_string_set(name, tmp);
|
||||||
|
if(!infrared_signal_read_body(signal, ff)) break;
|
||||||
|
success = true;
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
furi_string_free(tmp);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool infrared_signal_search_and_read(
|
||||||
|
InfraredSignal* signal,
|
||||||
|
FlipperFormat* ff,
|
||||||
|
const FuriString* name) {
|
||||||
|
bool success = false;
|
||||||
|
FuriString* tmp = furi_string_alloc();
|
||||||
|
|
||||||
|
do {
|
||||||
|
bool is_name_found = false;
|
||||||
|
while(flipper_format_read_string(ff, "name", tmp)) {
|
||||||
|
is_name_found = furi_string_equal(name, tmp);
|
||||||
|
if(is_name_found) break;
|
||||||
|
}
|
||||||
|
if(!is_name_found) break;
|
||||||
|
if(!infrared_signal_read_body(signal, ff)) break;
|
||||||
|
success = true;
|
||||||
|
} while(false);
|
||||||
|
|
||||||
|
furi_string_free(tmp);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
void infrared_signal_transmit(InfraredSignal* signal) {
|
||||||
|
if(signal->is_raw) {
|
||||||
|
InfraredRawSignal* raw_signal = &signal->payload.raw;
|
||||||
|
infrared_send_raw_ext(
|
||||||
|
raw_signal->timings,
|
||||||
|
raw_signal->timings_size,
|
||||||
|
true,
|
||||||
|
raw_signal->frequency,
|
||||||
|
raw_signal->duty_cycle);
|
||||||
|
} else {
|
||||||
|
InfraredMessage* message = &signal->payload.message;
|
||||||
|
infrared_send(message, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
45
applications/main/infrared/infrared_signal.h
Normal file
45
applications/main/infrared/infrared_signal.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <infrared.h>
|
||||||
|
#include <flipper_format/flipper_format.h>
|
||||||
|
|
||||||
|
typedef struct InfraredSignal InfraredSignal;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t timings_size;
|
||||||
|
uint32_t* timings;
|
||||||
|
uint32_t frequency;
|
||||||
|
float duty_cycle;
|
||||||
|
} InfraredRawSignal;
|
||||||
|
|
||||||
|
InfraredSignal* infrared_signal_alloc();
|
||||||
|
void infrared_signal_free(InfraredSignal* signal);
|
||||||
|
|
||||||
|
bool infrared_signal_is_raw(InfraredSignal* signal);
|
||||||
|
bool infrared_signal_is_valid(InfraredSignal* signal);
|
||||||
|
|
||||||
|
void infrared_signal_set_signal(InfraredSignal* signal, const InfraredSignal* other);
|
||||||
|
|
||||||
|
void infrared_signal_set_raw_signal(
|
||||||
|
InfraredSignal* signal,
|
||||||
|
const uint32_t* timings,
|
||||||
|
size_t timings_size,
|
||||||
|
uint32_t frequency,
|
||||||
|
float duty_cycle);
|
||||||
|
InfraredRawSignal* infrared_signal_get_raw_signal(InfraredSignal* signal);
|
||||||
|
|
||||||
|
void infrared_signal_set_message(InfraredSignal* signal, const InfraredMessage* message);
|
||||||
|
InfraredMessage* infrared_signal_get_message(InfraredSignal* signal);
|
||||||
|
|
||||||
|
bool infrared_signal_save(InfraredSignal* signal, FlipperFormat* ff, const char* name);
|
||||||
|
bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, FuriString* name);
|
||||||
|
bool infrared_signal_search_and_read(
|
||||||
|
InfraredSignal* signal,
|
||||||
|
FlipperFormat* ff,
|
||||||
|
const FuriString* name);
|
||||||
|
|
||||||
|
void infrared_signal_transmit(InfraredSignal* signal);
|
||||||
Reference in New Issue
Block a user