Загрузка данных
#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;
}