Загрузка данных


#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 */