While integrating File Manager app 2.5.2 with cFE 6.7.1 (OSAL 5.0.1) I ran into an issue. FM has a
command that allows users to receive a telemetry packet listing all of the open files. In order to do this FM needs to be able to query OSAL's file stream resource objects. The current OSAL implementation only allows a creator to query all of the resources objects by using OS_ForEachObject(). I wrote OSAL ticket #65 to recommend a more general query feature would be helpful. In OpenSatKit I added a new function OS_QueryObjectType() that allows anyone (not restricted to the creator) to query a resource type. The specific OSAL changes are below followed by the FM code that uses the function. These changes were made for OpenStaKit 2.1 that can be found at https://github.com/OpenSatKit/OpenSatKit.
This ticket can only be implemented once the OSAL is updated with a new feature that allows FM to query the resources objects.
osapi-os-core.h:
/*
** Typedef for object query OSAL callback functions. A query does not
** have to be performed by the object creator. All fields of the
** query_record are completed.
**
** This may be used by multiple APIs
*/
typedef struct
{
const char *name_entry;
uint32 creator;
uint16 refcount;
} OS_query_record_t;
typedef void (*OS_ObjQueryCallback_t)(OS_query_record_t *query_rec, void *callback_arg); //dcm - Added for OSK
/-------------------------------------------------------------------------------------/
/**
- @brief Query an object resource type maintained by the OSAL
- User supplied callback is called for all active resources of a particular type
- regardless of whether the caller created the object.
*/
uint32 OS_QueryObjectType (uint32 obj_type, OS_ObjQueryCallback_t callback_ptr, OS_query_record_t *query_rec, void *callback_arg); // dcm - Added for OSK
osapi-idmap.c:
/*----------------------------------------------------------------
*
- Function: OS_QueryObjectType
- Purpose: Implemented per public OSAL API
-
See description in API and header file for detail
-----------------------------------------------------------------/
uint32 OS_QueryObjectType (uint32 obj_type, OS_ObjQueryCallback_t callback_ptr, OS_query_record_t *query_rec, void *callback_arg)
{
uint32 obj_index;
uint32 obj_max;
uint32 obj_id;
uint32 active_obj_cnt = 0;
OS_common_record_t *obj_rec;
obj_max = OS_GetMaxForObjectType(obj_type);
if (obj_max > 0)
{
OS_Lock_Global_Impl(obj_type);
obj_index = OS_GetBaseForObjectType(obj_type);
while (obj_max > 0)
{
obj_rec = &OS_common_table[obj_index];
obj_id = obj_rec->active_id;
if (obj_id != 0)
{
query_rec->name_entry = obj_rec->name_entry;
query_rec->creator = obj_rec->creator;
query_rec->refcount = obj_rec->refcount;
/*
* Handle the object - Note that we must UN-lock before callback.
* The callback function might lock again in a different manner.
*/
OS_Unlock_Global_Impl(obj_type);
(*callback_ptr)(query_rec, callback_arg);
OS_Lock_Global_Impl(obj_type);
++active_obj_cnt;
}
++obj_index;
--obj_max;
}
OS_Unlock_Global_Impl(obj_type);
}
return active_obj_cnt;
} /* End OS_QueryObjectType() */
fm_cmd_utils.c:
static uint32 open_file_cnt = 0;
static void LoadOpenFileData(OS_query_record_t *query_rec, void *callback_arg)
{
FM_OpenFilesEntry_t *OpenFilesData = (FM_OpenFilesEntry_t *)callback_arg;
CFE_ES_TaskInfo_t TaskInfo;
if (OpenFilesData != (FM_OpenFilesEntry_t *) NULL)
{
/* FDTableEntry.Path has logical filename saved when file was opened */
strcpy(OpenFilesData[open_file_cnt].LogicalName, query_rec->name_entry);
/* Get the name of the application that opened the file */
CFE_PSP_MemSet(&TaskInfo, 0, sizeof(CFE_ES_TaskInfo_t));
if (CFE_ES_GetTaskInfo(&TaskInfo, query_rec->creator) == CFE_SUCCESS)
{
strcpy(OpenFilesData[open_file_cnt].AppName, (char *) TaskInfo.AppName);
}
}
++open_file_cnt;
} /* End LoadOpenFileData() */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ /
/ FM utility function -- get open files data /
/ /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 FM_GetOpenFilesData(FM_OpenFilesEntry_t *OpenFilesData)
{
OS_query_record_t query_rec;
open_file_cnt = 0;
OS_QueryObjectType (OS_OBJECT_TYPE_OS_STREAM, LoadOpenFileData, &query_rec, (void *)OpenFilesData);
return open_file_cnt;
} /* End FM_GetOpenFilesData */