KasperskyOS Community Edition 1.0

Сгенерированные методы и типы

При сборке решения компилятор NK на основе EDL-, CDL- и IDL-описаний генерирует набор специальных методов и типов, упрощающих формирование, отправку, прием и обработку IPC-сообщений.

Рассмотрим статическое описание сущности Server из примера echo. Это описание состоит из трех файлов: Server.edl, Ping.cdl и Ping.idl:

Server.edl

/* Описание сущности Server. */

entity Server

/* pingComp - именованный экземпляр компонента Ping. */

components {

pingComp: Ping

}

Ping.cdl

/* Описание компонента Ping. */

component Ping

/* pingImpl - реализация интерфейса Ping. */

interfaces {

pingImpl: Ping

}

Ping.idl

/* Описание интерфейса Ping. */

package Ping

interface {

Ping(in UInt32 value, out UInt32 result);

}

На основе этих файлов будут сгенерированы файлы Server.edl.h, Ping.cdl.h, и Ping.idl.h содержащие следующие методы и типы:

Методы и типы, общие для клиента и сервера

  • Абстрактные интерфейсы, содержащие указатели на реализации входящих в них методов.

    В нашем примере будет сгенерирован один абстрактный интерфейс – Ping:

    struct Ping_ops {

    nk_err_t (*Ping)(struct Ping *,

    const struct Ping_req *,

    const struct nk_arena *,

    struct Ping_res *,

    struct nk_arena *); };

    struct Ping {

    const struct Ping_ops *ops;

    };

  • Набор интерфейсных методов.

    При вызове интерфейсного метода в запросе автоматически проставляются соответствующие значения RIID и MID, после чего вызывается функция nk_transport_call().

    В нашем примере будет сгенерирован единственный интерфейсный метод Ping_Ping:

    nk_err_t Ping_Ping(struct Ping *,

    const struct Ping_Ping_req *,

    const struct nk_arena *,

    struct Ping_Ping_res *,

    struct nk_arena *);

Методы и типы, используемые только на клиенте

  • Типы прокси-объектов.

    Прокси-объект используется как аргумент интерфейсного метода. В нашем примере будет сгенерирован единственный тип прокси-объекта Ping_proxy:

    struct Ping_proxy {

    struct Ping base;

    struct nk_transport *transport;

    nk_iid_t iid;

    };

  • Функции для инициализации прокси-объектов.

    В нашем примере будет сгенерирована единственная инициализирующая функция Ping_proxy_init:

    void Ping_proxy_init(struct Ping_proxy *, struct nk_transport *, nk_iid_t);

  • Типы, определяющие структуру фиксированной части сообщения для каждого конкретного метода.

    В нашем примере будет сгенерировано два таких типа: Ping_Ping_req (для запроса) и Ping_Ping_res (для ответа).

    struct Ping_Ping_req {

    struct nk_message base_;

    nk_uint32_t value;

    };

    struct Ping_Ping_res {

    struct nk_message base_;

    nk_uint32_t result;

    };

Методы и типы, используемые только на сервере

  • Тип, содержащий реализации всех интерфейсов компонента, а также инициализирующая функция. (Для каждого компонента сервера.)

    При наличии вложенных компонентов этот тип также содержит их экземпляры, а инициализирующая функция принимает соответствующие им инициализированные структуры. Таким образом, при наличии вложенных компонентов, их инициализацию необходимо начинать с самого вложенного.

    В нашем примере будет сгенерирована структура Ping_component и функция Ping_component_init:

    struct Ping_component {

    struct Ping *pingImpl;

    };

    void Ping_component_init(struct Ping_component *, struct Ping *);

  • Тип, содержащий реализации всех интерфейсов предоставляемых сущностью-сервером непосредственно; все экземпляры компонентов, входящие в сущность-сервер; а также инициализирующая функция.

    В нашем примере будет сгенерирована структура Server_entity и функция Server_entity_init:

    struct Server_entity {

    struct Ping_component *pingComp;

    };

    void Server_entity_init(struct Server_entity *, struct Ping_component *);

  • Типы, определяющие структуру фиксированной части сообщения для любого метода конкретного интерфейса.

    В нашем примере будет сгенерировано два таких типа: Ping_req (для запроса) и Ping_res (для ответа).

    union Ping_req {

    struct nk_message base_;

    struct Ping_Ping_req Ping;

    };

    union Ping_res {

    struct nk_message base_;

    struct Ping_Ping_res Ping;

    };

  • Типы, определяющие структуру фиксированной части сообщения для любого метода любого интерфейса, реализация которого включена в конкретный компонент.

    При наличии вложенных компонентов эти типы также содержат структуры фиксированной части сообщения для любых методов любых интерфейсов, реализации которых включены во все вложенные компоненты.

    В нашем примере будет сгенерировано два таких типа: Ping_component_req (для запроса) и Ping_component_res (для ответа).

    union Ping_component_req {

    struct nk_message base_;

    union Ping_req pingImpl;

    };

    union Ping_component_res {

    struct nk_message base_;

    union Ping_res pingImpl;

    };

  • Типы, определяющие структуру фиксированной части сообщения для любого метода любого интерфейса, реализация которого включена в любой компонент, экземпляр которого входит в серверную сущность.

    При наличии вложенных компонентов эти типы также содержат структуры фиксированной части сообщения для любых методов любых интерфейсов, реализации которых включены во все вложенные компоненты.

    В нашем примере будет сгенерировано два таких типа: Server_entity_req (для запроса) и Server_entity_res (для ответа).

    union Server_entity_req {

    struct nk_message base_;

    union Ping_req pingComp_pingImpl;

    };

    union Server_entity_res {

    struct nk_message base_;

    union Ping_res pingComp_pingImpl;

    };

  • Dispatch-методы (диспетчеры) для отдельного интерфейса, компонента или сущности.

    Диспетчеры анализируют полученный запрос (значения RIID и MID), вызывают реализацию соответствующего метода, после чего сохраняют ответ в буфер. В нашем примере будут сгенерированы диспетчеры Ping_dispatch, Ping_component_dispatch и Server_entity_dispatch.

    Диспетчер сущности обрабатывает запрос и вызывает методы, реализуемые этой сущностью. Если запрос содержит некорректный RIID (например, относящийся к другой реализации интерфейса, которой нет у этой сущности) или некорректный MID, диспетчер возвращает NK_EOK или NK_ENOENT.

    nk_err_t Server_entity_dispatch(struct Server_entity *,

    const union Server_entity_req *,

    const struct nk_arena *,

    union Server_entity_res *,

    struct nk_arena *);

    В специальных случаях можно использовать диспетчеры интерфейса и компонента. Они принимают дополнительный аргумент – ID реализации интерфейса (nk_iid_t). Запрос будет обработан только если переданный аргумент и RIID из запроса совпадают, а MID корректен. В противном случае диспетчеры возвращают NK_EOK или NK_ENOENT.

    nk_err_t Ping_dispatch(struct Ping *,

    nk_iid_t,

    const union Ping_req *,

    const struct nk_arena *,

    union Ping_res *,

    struct nk_arena *);

    nk_err_t Ping_component_dispatch(struct Ping_component *,

    nk_iid_t,

    const union Ping_component_req *,

    const struct nk_arena *,

    union Ping_component_res *,

    struct nk_arena *);