For more details on initialization of transport to the client, preparation of the request and response structures, and the purpose of the server.edl.h
file, see the comments to the server.c
file in the echo example.
server.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
#include <coresrv/nk/transport-kos.h>
#include <coresrv/sl/sl_api.h>
#include "server.edl.h"
/* Type of interface implementation object. */
typedef struct IPingImpl {
struct IPing base;
int step;
} IPingImpl;
/* Ping method implementation. */
static nk_err_t Ping_impl(struct IPing *self, const struct IPing_Ping_req *req, const struct nk_arena* req_arena, struct IPing_Ping_res* res, struct nk_arena* res_arena)
{
IPingImpl *impl = (IPingImpl *)self;
/* The step is added to the "value" argument received in the request and we insert the
* result into the "result" argument. */
res->result = req->value + impl->step;
return NK_EOK;
}
/* Pong method implementation. */
static nk_err_t Pong_impl(struct IPing *self, const struct IPing_Pong_req *req, const struct nk_arena* req_arena, struct IPing_Pong_res* res, struct nk_arena* res_arena)
{
IPingImpl *impl = (IPingImpl *)self;
/* The step is added to the "value" argument received in the request and we insert the
* result into the "result" argument. */
res->result = req->value + impl->step;
return NK_EOK;
}
/* IPing object constructor.
* "step" is the step by which the input value is increased. */
struct IPing *CreateIPingImpl(int step)
{
/* Table of IPing interface method implementations. */
static const struct IPing_ops ops = {
.Ping = Ping_impl,
.Pong = Pong_impl
};
/* Object implementing the interface. */
static struct IPingImpl impl = {
.base = {&ops}
};
impl.step = step;
return &impl.base;
}
int main(void)
{
NkKosTransport transport;
ServiceId iid;
/* Get server IPC handle of "server_connection". */
Handle handle = ServiceLocatorRegister("server_connection", NULL, 0, &iid);
assert(handle != INVALID_HANDLE);
/* Initialize transport to client. */
NkKosTransport_Init(&transport, handle, NK_NULL, 0);
/* Prepare request structures: constant part and arena. */
union server_entity_req req;
char req_buffer[server_entity_req_arena_size];
struct nk_arena req_arena = NK_ARENA_INITIALIZER(req_buffer, req_buffer + sizeof(req_buffer));
/* Prepare response structures: constant part and arena. */
union server_entity_res res;
char res_buffer[server_entity_res_arena_size];
struct nk_arena res_arena = NK_ARENA_INITIALIZER(res_buffer, res_buffer + sizeof(res_buffer));
/* Initialize ping component dispatcher. 3 is the value of the "step",
* which will be added to the "value" input argument. */
struct ping_component component;
ping_component_init(&component, CreateIPingImpl(3));
/* Initialize server entity dispatcher. */
struct server_entity entity;
server_entity_init(&entity, &component);
fprintf(stderr, "Server: Hello I'm server\n");
do {
/* Initialize request constant part size. */
nk_req_reset(&req);
/* Initialize equest and response arena sizes. */
nk_arena_reset(&req_arena);
nk_arena_reset(&res_arena);
/* Awaiting request from client. */
if (nk_transport_recv(&transport.base, (struct nk_message *)&req, &req_arena) != NK_EOK)
fprintf(stderr, "nk_transport_recv error\n");
else
/* Process received request by calling implementation
* of requested Ping method (Ping_impl). */
server_entity_dispatch(&entity, &req, &req_arena, &res, &res_arena);
/* Send response. */
if (nk_transport_reply(&transport.base, (struct nk_message *)&res, &res_arena) != NK_EOK)
fprintf(stderr, "nk_transport_reply error\n");
} while (true);
return EXIT_SUCCESS;
}
Page top