| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- #include "furi.h"
- #include "cmsis_os.h"
- #include <string.h>
- // TODO: this file contains printf, that not implemented on uC target
- #ifdef FURI_DEBUG
- #include <stdio.h>
- #endif
- #define MAX_RECORD_COUNT 32
- static FuriRecord records[MAX_RECORD_COUNT];
- static size_t current_buffer_idx = 0;
- // find record pointer by name
- static FuriRecord* find_record(const char* name) {
- if(name == NULL) return NULL;
- FuriRecord* res = NULL;
- for(size_t i = 0; i < MAX_RECORD_COUNT; i++) {
- if(records[i].name != NULL && strcmp(name, records[i].name) == 0) {
- res = &records[i];
- }
- }
- return res;
- }
- bool furi_create(const char* name, void* value, size_t size) {
- #ifdef FURI_DEBUG
- printf("[FURI] creating %s record\n", name);
- #endif
- if(current_buffer_idx >= MAX_RECORD_COUNT) {
- // max record count exceed
- #ifdef FURI_DEBUG
- printf("[FURI] create: max record count exceed\n");
- #endif
- return NULL;
- }
- records[current_buffer_idx].mute_counter = 0;
- records[current_buffer_idx].mutex = xSemaphoreCreateMutexStatic(
- &records[current_buffer_idx].mutex_buffer
- );
- records[current_buffer_idx].value = value;
- records[current_buffer_idx].size = size;
- records[current_buffer_idx].name = name;
- for(size_t i = 0; i < MAX_RECORD_SUBSCRIBERS; i++) {
- records[current_buffer_idx].subscribers[i].allocated = false;
- }
- current_buffer_idx++;
- return true;
- }
- FuriRecordSubscriber* furi_open(
- const char* name,
- bool solo,
- bool no_mute,
- FlipperRecordCallback value_callback,
- FlipperRecordStateCallback state_callback
- ) {
- #ifdef FURI_DEBUG
- printf("[FURI] opening %s record\n", name);
- #endif
- // get furi record by name
- FuriRecord* record = find_record(name);
- if(record == NULL) {
- // cannot find record
- #ifdef FURI_DEBUG
- printf("[FURI] cannot find record %s\n", name);
- #endif
- return NULL;
- }
- // allocate subscriber
- FuriRecordSubscriber* subscriber = NULL;
- for(size_t i = 0; i < MAX_RECORD_SUBSCRIBERS; i++) {
- if(!record->subscribers[i].allocated) {
- subscriber = &record->subscribers[i];
- break;
- }
- }
- if(subscriber == NULL) {
- // cannot add subscriber (full)
- #ifdef FURI_DEBUG
- printf("[FURI] open: cannot add subscriber (full)\n");
- #endif
-
- return NULL;
- }
- // increase mute_counter
- if(solo) {
- record->mute_counter++;
- }
- // set all parameters
- subscriber->allocated = true;
- subscriber->mute_counter = record->mute_counter;
- subscriber->no_mute = no_mute;
- subscriber->cb = value_callback;
- subscriber->state_cb = state_callback;
- subscriber->record = record;
- // register record in application
- FuriApp* current_task = find_task(xTaskGetCurrentTaskHandle());
- if(current_task != NULL) {
- current_task->records[current_task->records_count] = record;
- current_task->records_count++;
- } else {
- #ifdef FURI_DEBUG
- printf("[FURI] open: no current task\n");
- #endif
- }
- return subscriber;
- }
- void furi_close(FuriRecordSubscriber* handler) {
- #ifdef FURI_DEBUG
- printf("[FURI] closing %s record\n", handler->record->name);
- #endif
- // deallocate subscriber
- handler->allocated = false;
- // set mute counter to next max value
- uint8_t max_mute_counter = 0;
- for(size_t i = 0; i < MAX_RECORD_SUBSCRIBERS; i++) {
- if(handler->record->subscribers[i].allocated) {
- if(handler->record->subscribers[i].mute_counter > max_mute_counter) {
- max_mute_counter = handler->record->subscribers[i].mute_counter;
- }
- }
- }
- handler->record->mute_counter = max_mute_counter;
- }
- static void furi_notify(FuriRecordSubscriber* handler, const void* value, size_t size) {
- for(size_t i = 0; i < MAX_RECORD_SUBSCRIBERS; i++) {
- if(handler->record->subscribers[i].allocated) {
- if(handler->record->subscribers[i].cb != NULL) {
- handler->record->subscribers[i].cb(value, size);
- }
- }
- }
- }
- void* furi_take(FuriRecordSubscriber* handler) {
- // take mutex
- return handler->record->value;
- }
- void furi_give(FuriRecordSubscriber* handler) {
- // release mutex
- }
- bool furi_read(FuriRecordSubscriber* handler, void* value, size_t size) {
- #ifdef FURI_DEBUG
- printf("[FURI] read from %s\n", handler->record->name);
- #endif
- if(handler == NULL || handler->record == NULL || value == NULL) return false;
- if(size > handler->record->size) return false;
- // return false if read from pipe
- if(handler->record->value == NULL) return false;
- furi_take(handler);
- memcpy(value, handler->record->value, size);
- furi_give(handler);
- furi_notify(handler, value, size);
- return true;
- }
- bool furi_write(FuriRecordSubscriber* handler, const void* value, size_t size) {
- #ifdef FURI_DEBUG
- printf("[FURI] write to %s\n", handler->record->name);
- #endif
- if(handler == NULL || handler->record == NULL || value == NULL) {
- #ifdef FURI_DEBUG
- printf("[FURI] write: null param %x %x\n", (uint32_t)(size_t)handler, (uint32_t)(size_t)value);
- #endif
- return false;
- }
- // check if closed
- if(!handler->allocated) {
- #ifdef FURI_DEBUG
- printf("[FURI] write: handler closed\n");
- #endif
- return false;
- }
- if(handler->record->value != NULL && size > handler->record->size) {
- #ifdef FURI_DEBUG
- printf("[FURI] write: wrong size %d\n", (uint32_t)size);
- #endif
- return false;
- }
- // check mute
- if(
- handler->record->mute_counter != handler->mute_counter
- && !handler->no_mute
- ) {
- #ifdef FURI_DEBUG
- printf("[FURI] write: muted\n");
- #endif
- return false;
- }
- if(handler->record->value != NULL) {
- // real write to value
- furi_take(handler);
- memcpy(handler->record->value, value, size);
- furi_give(handler);
- // notify subscribers
- furi_notify(handler, handler->record->value, handler->record->size);
- } else {
- furi_notify(handler, value, size);
- }
- return true;
- }
|