* Quicksave 1 * Header stage complete * Source stage complete * Lint & merge fixes * Includes * Documentation step 1 * FBT: output free size considering BT STACK * Documentation step 2 * py lint * Fix music player plugin * unit test stage 1: string allocator, mem, getters, setters, appends, compare, search. * unit test: string equality * unit test: string replace * unit test: string start_with, end_with * unit test: string trim * unit test: utf-8 * Rename * Revert fw_size changes * Simplify CLI backspace handling * Simplify CLI character insert * Merge fixes * Furi: correct filenaming and spelling * Bt: remove furi string include Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
		
			
				
	
	
		
			226 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			226 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include <furi.h>
 | 
						|
#include "protocol_dict.h"
 | 
						|
 | 
						|
struct ProtocolDict {
 | 
						|
    const ProtocolBase** base;
 | 
						|
    size_t count;
 | 
						|
    void** data;
 | 
						|
};
 | 
						|
 | 
						|
ProtocolDict* protocol_dict_alloc(const ProtocolBase** protocols, size_t count) {
 | 
						|
    ProtocolDict* dict = malloc(sizeof(ProtocolDict));
 | 
						|
    dict->base = protocols;
 | 
						|
    dict->count = count;
 | 
						|
    dict->data = malloc(sizeof(void*) * dict->count);
 | 
						|
 | 
						|
    for(size_t i = 0; i < dict->count; i++) {
 | 
						|
        dict->data[i] = dict->base[i]->alloc();
 | 
						|
    }
 | 
						|
 | 
						|
    return dict;
 | 
						|
}
 | 
						|
 | 
						|
void protocol_dict_free(ProtocolDict* dict) {
 | 
						|
    for(size_t i = 0; i < dict->count; i++) {
 | 
						|
        dict->base[i]->free(dict->data[i]);
 | 
						|
    }
 | 
						|
 | 
						|
    free(dict->data);
 | 
						|
    free(dict);
 | 
						|
}
 | 
						|
 | 
						|
void protocol_dict_set_data(
 | 
						|
    ProtocolDict* dict,
 | 
						|
    size_t protocol_index,
 | 
						|
    const uint8_t* data,
 | 
						|
    size_t data_size) {
 | 
						|
    furi_assert(protocol_index < dict->count);
 | 
						|
    furi_assert(dict->base[protocol_index]->get_data != NULL);
 | 
						|
    uint8_t* protocol_data = dict->base[protocol_index]->get_data(dict->data[protocol_index]);
 | 
						|
    size_t protocol_data_size = dict->base[protocol_index]->data_size;
 | 
						|
    furi_check(data_size >= protocol_data_size);
 | 
						|
    memcpy(protocol_data, data, protocol_data_size);
 | 
						|
}
 | 
						|
 | 
						|
void protocol_dict_get_data(
 | 
						|
    ProtocolDict* dict,
 | 
						|
    size_t protocol_index,
 | 
						|
    uint8_t* data,
 | 
						|
    size_t data_size) {
 | 
						|
    furi_assert(protocol_index < dict->count);
 | 
						|
    furi_assert(dict->base[protocol_index]->get_data != NULL);
 | 
						|
    uint8_t* protocol_data = dict->base[protocol_index]->get_data(dict->data[protocol_index]);
 | 
						|
    size_t protocol_data_size = dict->base[protocol_index]->data_size;
 | 
						|
    furi_check(data_size >= protocol_data_size);
 | 
						|
    memcpy(data, protocol_data, protocol_data_size);
 | 
						|
}
 | 
						|
 | 
						|
size_t protocol_dict_get_data_size(ProtocolDict* dict, size_t protocol_index) {
 | 
						|
    furi_assert(protocol_index < dict->count);
 | 
						|
    return dict->base[protocol_index]->data_size;
 | 
						|
}
 | 
						|
 | 
						|
size_t protocol_dict_get_max_data_size(ProtocolDict* dict) {
 | 
						|
    size_t max_data_size = 0;
 | 
						|
    for(size_t i = 0; i < dict->count; i++) {
 | 
						|
        size_t data_size = dict->base[i]->data_size;
 | 
						|
        if(data_size > max_data_size) {
 | 
						|
            max_data_size = data_size;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return max_data_size;
 | 
						|
}
 | 
						|
 | 
						|
const char* protocol_dict_get_name(ProtocolDict* dict, size_t protocol_index) {
 | 
						|
    furi_assert(protocol_index < dict->count);
 | 
						|
    return dict->base[protocol_index]->name;
 | 
						|
}
 | 
						|
 | 
						|
const char* protocol_dict_get_manufacturer(ProtocolDict* dict, size_t protocol_index) {
 | 
						|
    furi_assert(protocol_index < dict->count);
 | 
						|
    return dict->base[protocol_index]->manufacturer;
 | 
						|
}
 | 
						|
 | 
						|
void protocol_dict_decoders_start(ProtocolDict* dict) {
 | 
						|
    for(size_t i = 0; i < dict->count; i++) {
 | 
						|
        ProtocolDecoderStart fn = dict->base[i]->decoder.start;
 | 
						|
 | 
						|
        if(fn) {
 | 
						|
            fn(dict->data[i]);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
uint32_t protocol_dict_get_features(ProtocolDict* dict, size_t protocol_index) {
 | 
						|
    furi_assert(protocol_index < dict->count);
 | 
						|
    return dict->base[protocol_index]->features;
 | 
						|
}
 | 
						|
 | 
						|
ProtocolId protocol_dict_decoders_feed(ProtocolDict* dict, bool level, uint32_t duration) {
 | 
						|
    bool done = false;
 | 
						|
    ProtocolId ready_protocol_id = PROTOCOL_NO;
 | 
						|
 | 
						|
    for(size_t i = 0; i < dict->count; i++) {
 | 
						|
        ProtocolDecoderFeed fn = dict->base[i]->decoder.feed;
 | 
						|
 | 
						|
        if(fn) {
 | 
						|
            if(fn(dict->data[i], level, duration)) {
 | 
						|
                if(!done) {
 | 
						|
                    ready_protocol_id = i;
 | 
						|
                    done = true;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return ready_protocol_id;
 | 
						|
}
 | 
						|
 | 
						|
ProtocolId protocol_dict_decoders_feed_by_feature(
 | 
						|
    ProtocolDict* dict,
 | 
						|
    uint32_t feature,
 | 
						|
    bool level,
 | 
						|
    uint32_t duration) {
 | 
						|
    bool done = false;
 | 
						|
    ProtocolId ready_protocol_id = PROTOCOL_NO;
 | 
						|
 | 
						|
    for(size_t i = 0; i < dict->count; i++) {
 | 
						|
        uint32_t features = dict->base[i]->features;
 | 
						|
        if(features & feature) {
 | 
						|
            ProtocolDecoderFeed fn = dict->base[i]->decoder.feed;
 | 
						|
 | 
						|
            if(fn) {
 | 
						|
                if(fn(dict->data[i], level, duration)) {
 | 
						|
                    if(!done) {
 | 
						|
                        ready_protocol_id = i;
 | 
						|
                        done = true;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return ready_protocol_id;
 | 
						|
}
 | 
						|
 | 
						|
ProtocolId protocol_dict_decoders_feed_by_id(
 | 
						|
    ProtocolDict* dict,
 | 
						|
    size_t protocol_index,
 | 
						|
    bool level,
 | 
						|
    uint32_t duration) {
 | 
						|
    furi_assert(protocol_index < dict->count);
 | 
						|
 | 
						|
    ProtocolId ready_protocol_id = PROTOCOL_NO;
 | 
						|
    ProtocolDecoderFeed fn = dict->base[protocol_index]->decoder.feed;
 | 
						|
 | 
						|
    if(fn) {
 | 
						|
        if(fn(dict->data[protocol_index], level, duration)) {
 | 
						|
            ready_protocol_id = protocol_index;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return ready_protocol_id;
 | 
						|
}
 | 
						|
 | 
						|
bool protocol_dict_encoder_start(ProtocolDict* dict, size_t protocol_index) {
 | 
						|
    furi_assert(protocol_index < dict->count);
 | 
						|
    ProtocolEncoderStart fn = dict->base[protocol_index]->encoder.start;
 | 
						|
 | 
						|
    if(fn) {
 | 
						|
        return fn(dict->data[protocol_index]);
 | 
						|
    } else {
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
LevelDuration protocol_dict_encoder_yield(ProtocolDict* dict, size_t protocol_index) {
 | 
						|
    furi_assert(protocol_index < dict->count);
 | 
						|
    ProtocolEncoderYield fn = dict->base[protocol_index]->encoder.yield;
 | 
						|
 | 
						|
    if(fn) {
 | 
						|
        return fn(dict->data[protocol_index]);
 | 
						|
    } else {
 | 
						|
        return level_duration_reset();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void protocol_dict_render_data(ProtocolDict* dict, FuriString* result, size_t protocol_index) {
 | 
						|
    furi_assert(protocol_index < dict->count);
 | 
						|
    ProtocolRenderData fn = dict->base[protocol_index]->render_data;
 | 
						|
 | 
						|
    if(fn) {
 | 
						|
        return fn(dict->data[protocol_index], result);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void protocol_dict_render_brief_data(ProtocolDict* dict, FuriString* result, size_t protocol_index) {
 | 
						|
    furi_assert(protocol_index < dict->count);
 | 
						|
    ProtocolRenderData fn = dict->base[protocol_index]->render_brief_data;
 | 
						|
 | 
						|
    if(fn) {
 | 
						|
        return fn(dict->data[protocol_index], result);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
uint32_t protocol_dict_get_validate_count(ProtocolDict* dict, size_t protocol_index) {
 | 
						|
    furi_assert(protocol_index < dict->count);
 | 
						|
    return dict->base[protocol_index]->validate_count;
 | 
						|
}
 | 
						|
 | 
						|
ProtocolId protocol_dict_get_protocol_by_name(ProtocolDict* dict, const char* name) {
 | 
						|
    for(size_t i = 0; i < dict->count; i++) {
 | 
						|
        if(strcmp(name, protocol_dict_get_name(dict, i)) == 0) {
 | 
						|
            return i;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return PROTOCOL_NO;
 | 
						|
}
 | 
						|
 | 
						|
bool protocol_dict_get_write_data(ProtocolDict* dict, size_t protocol_index, void* data) {
 | 
						|
    furi_assert(protocol_index < dict->count);
 | 
						|
    ProtocolWriteData fn = dict->base[protocol_index]->write_data;
 | 
						|
 | 
						|
    furi_assert(fn);
 | 
						|
    return fn(dict->data[protocol_index], data);
 | 
						|
} |