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


#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

// Константы, совпадающие с логикой M7
#define SRTM_SERVICE_CAMERA_ID   (0x7F)
#define SRTM_VERSION             (0x01)

#define SRTM_CMD_CAMERA_ON       (0x01)
#define SRTM_CMD_CAMERA_OFF      (0x02)

// Типы пакетов SRTM
#define SRTM_TYPE_REQUEST        (0x00)
#define SRTM_TYPE_RESPONSE       (0x01)

// Коды возврата для ответа (M7 проверяет asyncReq->retCode)
#define SRTM_CAMERA_RETURN_CODE_SUCCESS (0x00)
#define SRTM_CAMERA_RETURN_CODE_ERROR   (0x01)

// Структура стандартного заголовка SRTM пакета
struct srtm_header {
    uint8_t category;
    uint8_t version;
    uint8_t command;
    uint8_t type;
} __attribute__((packed));

// Структура запроса от M7
struct camera_request {
    struct srtm_header head;
    uint8_t camera_id;
    // Если у вас в SRTM_CameraService_DoRequest передаются другие параметры, добавьте их сюда
} __attribute__((packed));

// Структура ответа обратно на M7
struct camera_response {
    struct srtm_header head;
    uint8_t ret_code; 
} __attribute__((packed));

// Функции-заглушки для реального управления камерой в Linux
void handle_camera_on(uint8_t camera_id) {
    printf("[Linux] Получена команда: ВКЛЮЧИТЬ камеру ID: %d\n", camera_id);
    // Пример: system("systemctl start camera_stream.service");
    // Или запуск пайплайна GStreamer / V4L2
}

void handle_camera_off(uint8_t camera_id) {
    printf("[Linux] Получена команда: ВЫКЛЮЧИТЬ камеру ID: %d\n", camera_id);
    // Пример: system("systemctl stop camera_stream.service");
}

int main(int argc, char *argv[]) {
    // Укажите ваш эндпоинт RPMSG (может отличаться в зависимости от dts, например /dev/rpmsg0)
    const char *device = "/dev/rpmsg0"; 
    if (argc > 1) {
        device = argv[1];
    }

    int fd = open(device, O_RDWR);
    if (fd < 0) {
        perror("Не удалось открыть устройство RPMSG");
        return EXIT_FAILURE;
    }

    printf("SRTM Деймон обработки камер запущен на %s. Ожидание команд от M7...\n", device);

    uint8_t rx_buffer[512];
    
    while (1) {
        // Блокирующее чтение пакета от ядра M7
        ssize_t bytes_read = read(fd, rx_buffer, sizeof(rx_buffer));
        if (bytes_read < 0) {
            perror("Ошибка чтения из RPMSG");
            close(fd);
            return EXIT_FAILURE;
        }

        if (bytes_read < (ssize_t)sizeof(struct srtm_header)) {
            fprintf(stderr, "Получен слишком короткий пакет (%ld байт)\n", bytes_read);
            continue;
        }

        struct camera_request *req = (struct camera_request *)rx_buffer;

        // Проверяем, наш ли это сервис (Камера) и является ли пакет Запросом (Request)
        if (req->head.category == SRTM_SERVICE_CAMERA_ID && req->head.type == SRTM_TYPE_REQUEST) {
            
            uint8_t cam_id = req->camera_id;
            uint8_t cmd = req->head.command;
            uint8_t status_to_send = SRTM_CAMERA_RETURN_CODE_SUCCESS;

            // Обработка команд
            if (cmd == SRTM_CMD_CAMERA_ON) {
                handle_camera_on(cam_id);
            } else if (cmd == SRTM_CMD_CAMERA_OFF) {
                handle_camera_off(cam_id);
            } else {
                fprintf(stderr, "Неизвестная ID команды: 0x%02X\n", cmd);
                status_to_send = SRTM_CAMERA_RETURN_CODE_ERROR;
            }

            // Формируем ответ (Response) для М7, чтобы он вышел из блокировки ожидания семафора
            struct camera_response resp;
            resp.head.category = SRTM_SERVICE_CAMERA_ID;
            resp.head.version  = SRTM_VERSION;
            resp.head.command  = cmd;
            resp.head.type     = SRTM_TYPE_RESPONSE; // Меняем тип на Response
            resp.ret_code      = status_to_send;     // Результат выполнения

            // Отправляем пакет обратно на M7
            ssize_t bytes_written = write(fd, &resp, sizeof(resp));
            if (bytes_written < 0) {
                perror("Не удалось отправить ответ на M7");
            }
        }
    }

    close(fd);
    return EXIT_SUCCESS;
}