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


#include "srtm_camera_service.h"
#include "srtm_heap.h"
#include "srtm_dispatcher.h"
#include "srtm_message.h"
#include "srtm_service_struct.h"
#include <string.h>
#include <assert.h>

/* Внутренняя структура сервиса */
typedef struct _srtm_camera_service
{
    struct _srtm_service service;
    srtm_camera_adapter_t adapter;
} *srtm_camera_service_t;

/* Прототипы внутренних функций */
static srtm_status_t SRTM_CameraService_Request(srtm_service_t service, srtm_request_t request);
static srtm_status_t SRTM_CameraService_Notify(srtm_service_t service, srtm_notification_t notif);

/**
 * @brief Создание сервиса управления камерой
 */
srtm_service_t SRTM_CameraService_Create(srtm_camera_adapter_t adapter)
{
    srtm_camera_service_t handle;

    SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);
    
    handle = (srtm_camera_service_t)SRTM_Heap_Malloc(sizeof(struct _srtm_camera_service));
    assert(handle);

    adapter->service = &handle->service;
    handle->adapter  = adapter;

    /* Инициализация базовых полей сервиса SRTM */
    SRTM_List_Init(&handle->service.node);
    handle->service.dispatcher = NULL;
    handle->service.category   = SRTM_CAMERA_CATEGORY;
    handle->service.destroy    = SRTM_CameraService_Destroy;
    handle->service.request    = SRTM_CameraService_Request;
    handle->service.notify     = SRTM_CameraService_Notify;

    return &handle->service;
}

/**
 * @brief Уничтожение сервиса
 */
void SRTM_CameraService_Destroy(srtm_service_t service)
{
    srtm_camera_service_t handle = (srtm_camera_service_t)(void *)service;

    assert(service);
    SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);

    /* Сервис должен быть отключен от диспетчера перед удалением */
    assert(SRTM_List_IsEmpty(&service->node));

    SRTM_Heap_Free(handle);
}

/**
 * @brief Сброс состояния сервиса
 */
void SRTM_CameraService_Reset(srtm_service_t service, srtm_peercore_t core)
{
    assert(service);
    SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);
    /* Тут можно добавить сброс пинов камеры в исходное состояние при перезагрузке Linux */
}

/**
 * @brief Обработчик входящих запросов (Requests) от Linux (A55)
 */
static srtm_status_t SRTM_CameraService_Request(srtm_service_t service, srtm_request_t request)
{
    srtm_camera_service_t handle = (srtm_camera_service_t)(void *)service;
    srtm_camera_adapter_t adapter = handle->adapter;
    srtm_status_t status;
    srtm_channel_t channel;
    uint8_t command;
    uint32_t payloadLen;
    srtm_response_t response;
    struct _srtm_camera_payload *camReq;
    struct _srtm_camera_payload *camResp;

    assert(service->dispatcher);
    SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);

    /* Извлекаем метаданные из входящего сообщения */
    channel    = SRTM_CommMessage_GetChannel(request);
    command    = SRTM_CommMessage_GetCommand(request);
    camReq     = (struct _srtm_camera_payload *)(void *)SRTM_CommMessage_GetPayload(request);
    payloadLen = SRTM_CommMessage_GetPayloadLen(request);
    
    assert(camReq);
    assert(payloadLen >= sizeof(struct _srtm_camera_payload));

    /* Создаем ответный контейнер (Response) */
    response = SRTM_Response_Create(channel, SRTM_CAMERA_CATEGORY, SRTM_CAMERA_VERSION, command,
                                    (uint16_t)sizeof(struct _srtm_camera_payload));
    if (response == NULL)
    {
        return SRTM_Status_OutOfMemory;
    }

    camResp = (struct _srtm_camera_payload *)(void *)SRTM_CommMessage_GetPayload(response);

    /* Проверка совместимости версий протокола */
    status = SRTM_Service_CheckVersion(service, request, SRTM_CAMERA_VERSION);
    if (status != SRTM_Status_Success)
    {
        SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_WARN, "%s: версия протокола не поддерживается!\r\n", __func__);
        camResp->retCode = SRTM_CAMERA_RETURN_CODE_UNSUPPORTED;
    }
    else
    {
        SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO,
                           "SRTM М7 получил запрос Камеры: cmd=%d, cameraID=%d\r\n", command, camReq->cameraID);
        
        /* Копируем базовый payload (ID камеры) в структуру ответа */
        camResp->cameraID = camReq->cameraID;

        /* Диспетчеризация команд START / STOP */
        switch (command)
        {
            case (uint8_t)SRTM_CAMERA_CMD_START:
                if (adapter->start != NULL)
                {
                    status = adapter->start(adapter, camReq->cameraID);
                    camResp->retCode = (status == SRTM_Status_Success) ? 
                                       SRTM_CAMERA_RETURN_CODE_SUCCESS : SRTM_CAMERA_RETURN_CODE_FAIL;
                }
                else
                {
                    camResp->retCode = SRTM_CAMERA_RETURN_CODE_FAIL;
                }
                break;

            case (uint8_t)SRTM_CAMERA_CMD_STOP:
                if (adapter->stop != NULL)
                {
                    status = adapter->stop(adapter, camReq->cameraID);
                    camResp->retCode = (status == SRTM_Status_Success) ? 
                                       SRTM_CAMERA_RETURN_CODE_SUCCESS : SRTM_CAMERA_RETURN_CODE_FAIL;
                }
                else
                {
                    camResp->retCode = SRTM_CAMERA_RETURN_CODE_FAIL;
                }
                break;

            default:
                SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_WARN, "%s: команда %d не поддерживается!\r\n", __func__, command);
                camResp->retCode = SRTM_CAMERA_RETURN_CODE_UNSUPPORTED;
                break;
        }
    }

    /* Отправляем сформированный ответ назад в Linux через SRTM диспетчер */
    return SRTM_Dispatcher_DeliverResponse(service->dispatcher, response);
}

/**
 * @brief Обработчик уведомлений (Notifications) — для данного сервиса не используются
 */
static srtm_status_t SRTM_CameraService_Notify(srtm_service_t service, srtm_notification_t notif)
{
    SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_WARN, "%s: уведомления не поддерживаются текущей логикой!\r\n", __func__);
    return SRTM_Status_ServiceNotFound;
}