This repository has been archived by the owner on Aug 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
partial fs support and furipubsub support
- Loading branch information
Showing
9 changed files
with
932 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
#include "pubsub.h" | ||
#include "check.h" | ||
#include "mutex.h" | ||
|
||
#include <m-list.h> | ||
|
||
struct FuriPubSubSubscription { | ||
FuriPubSubCallback callback; | ||
void* callback_context; | ||
}; | ||
|
||
LIST_DEF(FuriPubSubSubscriptionList, FuriPubSubSubscription, M_POD_OPLIST); | ||
|
||
struct FuriPubSub { | ||
FuriPubSubSubscriptionList_t items; | ||
FuriMutex* mutex; | ||
}; | ||
|
||
FuriPubSub* furi_pubsub_alloc() { | ||
FuriPubSub* pubsub = malloc(sizeof(FuriPubSub)); | ||
|
||
pubsub->mutex = furi_mutex_alloc(FuriMutexTypeNormal); | ||
furi_assert(pubsub->mutex); | ||
|
||
FuriPubSubSubscriptionList_init(pubsub->items); | ||
|
||
return pubsub; | ||
} | ||
|
||
void furi_pubsub_free(FuriPubSub* pubsub) { | ||
furi_assert(pubsub); | ||
|
||
furi_check(FuriPubSubSubscriptionList_size(pubsub->items) == 0); | ||
|
||
FuriPubSubSubscriptionList_clear(pubsub->items); | ||
|
||
furi_mutex_free(pubsub->mutex); | ||
|
||
free(pubsub); | ||
} | ||
|
||
FuriPubSubSubscription* | ||
furi_pubsub_subscribe(FuriPubSub* pubsub, FuriPubSubCallback callback, void* callback_context) { | ||
furi_check(furi_mutex_acquire(pubsub->mutex, FuriWaitForever) == FuriStatusOk); | ||
// put uninitialized item to the list | ||
FuriPubSubSubscription* item = FuriPubSubSubscriptionList_push_raw(pubsub->items); | ||
|
||
// initialize item | ||
item->callback = callback; | ||
item->callback_context = callback_context; | ||
|
||
furi_check(furi_mutex_release(pubsub->mutex) == FuriStatusOk); | ||
|
||
return item; | ||
} | ||
|
||
void furi_pubsub_unsubscribe(FuriPubSub* pubsub, FuriPubSubSubscription* pubsub_subscription) { | ||
furi_assert(pubsub); | ||
furi_assert(pubsub_subscription); | ||
|
||
furi_check(furi_mutex_acquire(pubsub->mutex, FuriWaitForever) == FuriStatusOk); | ||
bool result = false; | ||
|
||
// iterate over items | ||
FuriPubSubSubscriptionList_it_t it; | ||
for(FuriPubSubSubscriptionList_it(it, pubsub->items); !FuriPubSubSubscriptionList_end_p(it); | ||
FuriPubSubSubscriptionList_next(it)) { | ||
const FuriPubSubSubscription* item = FuriPubSubSubscriptionList_cref(it); | ||
|
||
// if the iterator is equal to our element | ||
if(item == pubsub_subscription) { | ||
FuriPubSubSubscriptionList_remove(pubsub->items, it); | ||
result = true; | ||
break; | ||
} | ||
} | ||
|
||
furi_check(furi_mutex_release(pubsub->mutex) == FuriStatusOk); | ||
furi_check(result); | ||
} | ||
|
||
void furi_pubsub_publish(FuriPubSub* pubsub, void* message) { | ||
furi_check(furi_mutex_acquire(pubsub->mutex, FuriWaitForever) == FuriStatusOk); | ||
|
||
// iterate over subscribers | ||
FuriPubSubSubscriptionList_it_t it; | ||
for(FuriPubSubSubscriptionList_it(it, pubsub->items); !FuriPubSubSubscriptionList_end_p(it); | ||
FuriPubSubSubscriptionList_next(it)) { | ||
const FuriPubSubSubscription* item = FuriPubSubSubscriptionList_cref(it); | ||
item->callback(message, item->callback_context); | ||
} | ||
|
||
furi_check(furi_mutex_release(pubsub->mutex) == FuriStatusOk); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/** | ||
* @file pubsub.h | ||
* FuriPubSub | ||
*/ | ||
#pragma once | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** FuriPubSub Callback type */ | ||
typedef void (*FuriPubSubCallback)(const void* message, void* context); | ||
|
||
/** FuriPubSub type */ | ||
typedef struct FuriPubSub FuriPubSub; | ||
|
||
/** FuriPubSubSubscription type */ | ||
typedef struct FuriPubSubSubscription FuriPubSubSubscription; | ||
|
||
/** Allocate FuriPubSub | ||
* | ||
* Reentrable, Not threadsafe, one owner | ||
* | ||
* @return pointer to FuriPubSub instance | ||
*/ | ||
FuriPubSub* furi_pubsub_alloc(); | ||
|
||
/** Free FuriPubSub | ||
* | ||
* @param pubsub FuriPubSub instance | ||
*/ | ||
void furi_pubsub_free(FuriPubSub* pubsub); | ||
|
||
/** Subscribe to FuriPubSub | ||
* | ||
* Threadsafe, Reentrable | ||
* | ||
* @param pubsub pointer to FuriPubSub instance | ||
* @param[in] callback The callback | ||
* @param callback_context The callback context | ||
* | ||
* @return pointer to FuriPubSubSubscription instance | ||
*/ | ||
FuriPubSubSubscription* | ||
furi_pubsub_subscribe(FuriPubSub* pubsub, FuriPubSubCallback callback, void* callback_context); | ||
|
||
/** Unsubscribe from FuriPubSub | ||
* | ||
* No use of `pubsub_subscription` allowed after call of this method | ||
* Threadsafe, Reentrable. | ||
* | ||
* @param pubsub pointer to FuriPubSub instance | ||
* @param pubsub_subscription pointer to FuriPubSubSubscription instance | ||
*/ | ||
void furi_pubsub_unsubscribe(FuriPubSub* pubsub, FuriPubSubSubscription* pubsub_subscription); | ||
|
||
/** Publish message to FuriPubSub | ||
* | ||
* Threadsafe, Reentrable. | ||
* | ||
* @param pubsub pointer to FuriPubSub instance | ||
* @param message message pointer to publish | ||
*/ | ||
void furi_pubsub_publish(FuriPubSub* pubsub, void* message); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#include "filesystem_api_defines.h" | ||
|
||
const char* filesystem_api_error_get_desc(FS_Error error_id) { | ||
const char* result = "unknown error"; | ||
switch(error_id) { | ||
case(FSE_OK): | ||
result = "OK"; | ||
break; | ||
case(FSE_NOT_READY): | ||
result = "filesystem not ready"; | ||
break; | ||
case(FSE_EXIST): | ||
result = "file/dir already exist"; | ||
break; | ||
case(FSE_NOT_EXIST): | ||
result = "file/dir not exist"; | ||
break; | ||
case(FSE_INVALID_PARAMETER): | ||
result = "invalid parameter"; | ||
break; | ||
case(FSE_DENIED): | ||
result = "access denied"; | ||
break; | ||
case(FSE_INVALID_NAME): | ||
result = "invalid name/path"; | ||
break; | ||
case(FSE_INTERNAL): | ||
result = "internal error"; | ||
break; | ||
case(FSE_NOT_IMPLEMENTED): | ||
result = "function not implemented"; | ||
break; | ||
case(FSE_ALREADY_OPEN): | ||
result = "file is already open"; | ||
break; | ||
} | ||
return result; | ||
} | ||
|
||
bool file_info_is_dir(const FileInfo* file_info) { | ||
return (file_info->flags & FSF_DIRECTORY); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#pragma once | ||
#include <stdint.h> | ||
#include <stdbool.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** Access mode flags */ | ||
typedef enum { | ||
FSAM_READ = (1 << 0), /**< Read access */ | ||
FSAM_WRITE = (1 << 1), /**< Write access */ | ||
FSAM_READ_WRITE = FSAM_READ | FSAM_WRITE, /**< Read and write access */ | ||
} FS_AccessMode; | ||
|
||
/** Open mode flags */ | ||
typedef enum { | ||
FSOM_OPEN_EXISTING = 1, /**< Open file, fail if file doesn't exist */ | ||
FSOM_OPEN_ALWAYS = 2, /**< Open file. Create new file if not exist */ | ||
FSOM_OPEN_APPEND = 4, /**< Open file. Create new file if not exist. Set R/W pointer to EOF */ | ||
FSOM_CREATE_NEW = 8, /**< Creates a new file. Fails if the file is exist */ | ||
FSOM_CREATE_ALWAYS = 16, /**< Creates a new file. If file exist, truncate to zero size */ | ||
} FS_OpenMode; | ||
|
||
/** API errors enumeration */ | ||
typedef enum { | ||
FSE_OK, /**< No error */ | ||
FSE_NOT_READY, /**< FS not ready */ | ||
FSE_EXIST, /**< File/Dir already exist */ | ||
FSE_NOT_EXIST, /**< File/Dir does not exist */ | ||
FSE_INVALID_PARAMETER, /**< Invalid API parameter */ | ||
FSE_DENIED, /**< Access denied */ | ||
FSE_INVALID_NAME, /**< Invalid name/path */ | ||
FSE_INTERNAL, /**< Internal error */ | ||
FSE_NOT_IMPLEMENTED, /**< Function not implemented */ | ||
FSE_ALREADY_OPEN, /**< File/Dir already opened */ | ||
} FS_Error; | ||
|
||
/** FileInfo flags */ | ||
typedef enum { | ||
FSF_DIRECTORY = (1 << 0), /**< Directory */ | ||
} FS_Flags; | ||
|
||
/** Structure that hold file index and returned api errors */ | ||
typedef struct File File; | ||
|
||
/** Structure that hold file info */ | ||
typedef struct { | ||
uint8_t flags; /**< flags from FS_Flags enum */ | ||
uint64_t size; /**< file size */ | ||
} FileInfo; | ||
|
||
/** Gets the error text from FS_Error | ||
* @param error_id error id | ||
* @return const char* error text | ||
*/ | ||
const char* filesystem_api_error_get_desc(FS_Error error_id); | ||
|
||
/** Checks if file info is directory | ||
* @param file_info file info pointer | ||
* @return bool is directory | ||
*/ | ||
bool file_info_is_dir(const FileInfo* file_info); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
Oops, something went wrong.