Загрузка данных
#include <assert.h>
#include <string.h>
#include "fsl_common.h"
#include "srtm_camera_service.h"
#include "srtm_heap.h"
#include "srtm_list.h"
#include "srtm_dispatcher.h"
#include "srtm_service.h"
#include "srtm_service_struct.h"
#include "srtm_channel.h"
#include "srtm_channel_struct.h"
#include "srtm_peercore.h"
#include "srtm_peercore_struct.h"
#include "srtm_message.h"
#include "srtm_message_struct.h"
#include "srtm_mutex.h"
#include "srtm_sem.h"
#include "srtm_procedure.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Implementation block context reflecting NXP infrastructure template layout */
typedef struct _srtm_camera_service
{
struct _srtm_service service;
srtm_peercore_t activeCore; /* Track operational peer target handles */
} *srtm_camera_service_t;
/* State machine parameters mapping directly into your provided code schema */
typedef enum _srtm_camera_async_req_state
{
SRTM_CAMERA_ASYNC_REQ_STATE_INIT = 0U,
SRTM_CAMERA_ASYNC_REQ_STATE_WAITING,
SRTM_CAMERA_ASYNC_REQ_STATE_CANCELLED,
SRTM_CAMERA_ASYNC_REQ_STATE_FINISHED
} srtm_camera_async_req_state_t;
SRTM_ANON_DEC_BEGIN
typedef struct _srtm_camera_async_req
{
bool syncResult; /* Synchronous flag switch */
srtm_mutex_t mutex;
srtm_sem_t sem;
srtm_service_t service;
uint8_t retCode;
uint8_t cameraID;
uint8_t command;
union
{
srtm_camera_cmd_cb_t resultCb;
};
union
{
void *resultCbParam;
};
srtm_camera_async_req_state_t reqState;
} *srtm_camera_async_req_t;
SRTM_ANON_DEC_END
/*******************************************************************************
* Prototypes
******************************************************************************/
static srtm_status_t SRTM_CameraClient_Request(srtm_service_t service, srtm_request_t request);
static srtm_status_t SRTM_CameraClient_Notify(srtm_service_t service, srtm_notification_t notif);
/*******************************************************************************
* Code
******************************************************************************/
/* Memory cleanup routing mirroring SRTM_AutoService_DestroyAsyncReq */
static void SRTM_CameraService_DestroyAsyncReq(srtm_camera_async_req_t req)
{
if (req->mutex)
{
SRTM_Mutex_Destroy(req->mutex);
}
if (req->sem)
{
SRTM_Sem_Destroy(req->sem);
}
SRTM_Heap_Free(req);
}
/* Tracking allocation mirroring SRTM_AutoService_CreateAsyncReq */
static srtm_camera_async_req_t SRTM_CameraService_CreateAsyncReq(srtm_service_t service)
{
srtm_camera_async_req_t req;
req = (srtm_camera_async_req_t)SRTM_Heap_Malloc(sizeof(struct _srtm_camera_async_req));
if (req)
{
(void)memset(req, 0, sizeof(struct _srtm_camera_async_req));
req->mutex = SRTM_Mutex_Create();
req->sem = SRTM_Sem_Create(1, 0);
if (!req->mutex || !req->sem)
{
SRTM_CameraService_DestroyAsyncReq(req);
req = NULL;
}
else
{
req->service = service;
}
}
return req;
}
/* Dispatcher-safe routine mapping directly into your ResponseCallback logic */
static void SRTM_CameraService_ResponseCallback(srtm_dispatcher_t disp,
srtm_message_t req,
srtm_message_t resp,
void *param)
{
srtm_camera_async_req_t asyncReq = (srtm_camera_async_req_t)param;
struct _srtm_camera_payload *camResp;
uint32_t payloadLen = 0;
bool freeAsyncReq = false;
camResp = resp ? (struct _srtm_camera_payload *)SRTM_CommMessage_GetPayload(resp) : NULL;
if (camResp)
{
payloadLen = SRTM_CommMessage_GetPayloadLen(resp);
if (payloadLen < sizeof(struct _srtm_camera_payload))
{
assert(false);
}
}
SRTM_Mutex_Lock(asyncReq->mutex);
if (asyncReq->reqState == SRTM_CAMERA_ASYNC_REQ_STATE_WAITING)
{
asyncReq->retCode = camResp ? camResp->retCode : (uint8_t)SRTM_CAMERA_RETURN_CODE_FAIL;
if (asyncReq->syncResult)
{
/* Trigger synchronous thread processing unblock via semaphore post */
SRTM_Sem_Post(asyncReq->sem);
}
else
{
/* Invoke client handler within asynchronous task loops */
if (asyncReq->resultCb)
{
asyncReq->resultCb(asyncReq->service, asyncReq->cameraID, asyncReq->command,
asyncReq->retCode, asyncReq->resultCbParam);
}
freeAsyncReq = true;
}
asyncReq->reqState = SRTM_CAMERA_ASYNC_REQ_STATE_FINISHED;
}
else
{
freeAsyncReq = true;
}
SRTM_Mutex_Unlock(asyncReq->mutex);
if (freeAsyncReq)
{
SRTM_CameraService_DestroyAsyncReq(asyncReq);
}
}
/* Thread context safe execution module mirroring SRTM_AutoService_DeliverRequest */
static void SRTM_CameraService_DeliverRequest(srtm_dispatcher_t dispatcher, void *param1, void *param2)
{
srtm_camera_async_req_t asyncReq = (srtm_camera_async_req_t)param1;
srtm_camera_service_t handle = (srtm_camera_service_t)asyncReq->service;
srtm_request_t req = (srtm_request_t)param2;
srtm_status_t status;
if (handle->activeCore && SRTM_PeerCore_IsConnected(handle->activeCore))
{
/* Dynamically resolve communication endpoints mapped to our category */
req->channel = SRTM_PeerCore_GetChannel(handle->activeCore, SRTM_CAMERA_CATEGORY);
if (req->channel)
{
status = SRTM_Dispatcher_DeliverRequest(dispatcher, req, SRTM_CameraService_ResponseCallback, param1);
if (status == SRTM_Status_Success)
{
asyncReq->reqState = SRTM_CAMERA_ASYNC_REQ_STATE_WAITING;
return;
}
}
}
/* Fallback processing parameters for interface drop exceptions */
asyncReq->reqState = SRTM_CAMERA_ASYNC_REQ_STATE_FINISHED;
if (asyncReq->syncResult)
{
SRTM_Sem_Post(asyncReq->sem);
}
else
{
SRTM_CameraService_DestroyAsyncReq(asyncReq);
}
SRTM_Request_Destroy(req);
}
/* Pipeline setup routine duplicating SRTM_AutoService_DoRequest design principles */
static srtm_status_t SRTM_CameraService_DoRequest(srtm_camera_async_req_t asyncReq, uint8_t cameraID, uint8_t cmd)
{
srtm_request_t req;
struct _srtm_camera_payload *camReq;
srtm_status_t status;
srtm_procedure_t proc;
/* Initialize tracking request block without hardcoding targeted endpoint parameters */
req = SRTM_Request_Create(NULL, SRTM_CAMERA_CATEGORY, SRTM_CAMERA_VERSION, cmd, sizeof(struct _srtm_camera_payload));
if (!req)
{
return SRTM_Status_OutOfMemory;
}
camReq = (struct _srtm_camera_payload *)SRTM_CommMessage_GetPayload(req);
camReq->cameraID = cameraID;
camReq->retCode = 0;
/* Create cross-thread task procedure context safely */
proc = SRTM_Procedure_Create(SRTM_CameraService_DeliverRequest, asyncReq, req);
if (!proc)
{
SRTM_Request_Destroy(req);
return SRTM_Status_OutOfMemory;
}
/* Synchronously call dispatcher procedure mapping */
status = SRTM_Dispatcher_CallProc(asyncReq->service->dispatcher, proc, SRTM_WAIT_FOR_EVER);
if (status != SRTM_Status_Success || asyncReq->reqState == SRTM_CAMERA_ASYNC_REQ_STATE_INIT)
{
SRTM_Request_Destroy(req);
status = SRTM_Status_Error;
}
SRTM_Procedure_Destroy(proc);
return status;
}
/* Operational API routing logic duplicating SRTM_AutoService_SendCommand logic patterns */
static srtm_status_t SRTM_CameraClient_SendCmd(srtm_service_t service,
uint8_t cameraID,
uint8_t cmd,
bool sync,
srtm_camera_cmd_cb_t cb,
void *param,
uint32_t timeout_ms)
{
srtm_status_t status;
srtm_camera_async_req_t asyncReq;
bool freeAsyncReq = true;
assert(service);
asyncReq = SRTM_CameraService_CreateAsyncReq(service);
if (!asyncReq)
{
return SRTM_Status_OutOfMemory;
}
asyncReq->syncResult = sync;
asyncReq->cameraID = cameraID;
asyncReq->command = cmd;
asyncReq->resultCb = cb;
asyncReq->resultCbParam = param;
status = SRTM_CameraService_DoRequest(asyncReq, cameraID, cmd);
if (status == SRTM_Status_Success)
{
if (sync)
{
/* Intercept blocking validation parameter rules */
assert(timeout_ms > 0);
SRTM_Sem_Wait(asyncReq->sem, timeout_ms);
SRTM_Mutex_Lock(asyncReq->mutex);
if (asyncReq->reqState != SRTM_CAMERA_ASYNC_REQ_STATE_FINISHED)
{
asyncReq->reqState = SRTM_CAMERA_ASYNC_REQ_STATE_CANCELLED;
status = SRTM_Status_Timeout;
}
else
{
status = (asyncReq->retCode == SRTM_CAMERA_RETURN_CODE_SUCCESS) ?
SRTM_Status_Success : SRTM_Status_Error;
}
SRTM_Mutex_Unlock(asyncReq->mutex);
}
else
{
/* Asynchronous pipeline tracking passed to internal handlers safely */
freeAsyncReq = false;
}
}
if (freeAsyncReq)
{
SRTM_CameraService_DestroyAsyncReq(asyncReq);
}
return status;
}
/* Public Synchronous wrapper API definitions */