valid_picture_client.c
#include "defer_to_kernel_common_client.h"
static const char EntityName[] = "ValidPictureClient";
static Retcode GetService(
NsHandle ns, char *server, char *service, rtl_size_t timeout)
{
Retcode rc = rcOk;
rtl_size_t start = KnGetMSecSinceStart();
/**
* Here the client entity is trying to find out whether the PictureManager entity (server)
* has the required Interface Type and gets the corresponding service name. Because
* interface publishing by the PictureManager entity and polling of interfaces by
* client entities are asynchronous events, polling is performed cyclically
* with a time delay (timeout).
*/
do
{
rc = NsEnumServices(
ns, InterfaceType, INTERFACE_INDEX, server, service);
if (rc == rcResourceNotFound)
{
rtl_size_t delta = KnGetMSecSinceStart() - start;
if (delta < timeout)
{
KnSleep(rtl_min(RISEUP_TIMEOUT_MSEC, (timeout - delta)));
}
else
{
rc = rcTimeout;
}
}
}
while (rc == rcResourceNotFound);
return rc;
}
static Retcode ConnectToPictureManager(char *server, char *service)
{
Retcode rc = rcOk;
NsHandle ns = INVALID_HANDLE;
rc = NsCreate(RTL_NULL, NS_WAIT_TIME_MS, &ns);
if (rc == rcOk)
{
rc = GetService(ns, server, service, TIMEOUT_MSEC);
}
return rc;
}
static void PrintResponse(Get_GetPictures_res *res, struct nk_arena *resArena)
{
int i;
nk_ptr_t *paths;
nk_uint32_t numPaths;
paths = nk_arena_get(nk_ptr_t, resArena, &res->resultSeq, &numPaths);
fprintf(stderr, "[%s]: Get from PictureManager:\n", EntityName);
for (i = 0; i < numPaths; i++)
{
nk_char_t *rev;
nk_uint32_t slen = 0;
rev = nk_arena_get(nk_char_t, resArena, &paths[i], &slen);
fprintf(stderr, "[%s]: %s\n", EntityName, rev);
}
}
/* Entry point in the ValidPictureClient entity. */
int main(int argc, const char *argv[])
{
Retcode rc = rcOk;
Handle handle = INVALID_HANDLE;
rtl_uint32_t rsid = INVALID_RID;
struct Get_proxy proxy;
NkKosTransport transport;
char server[UCORE_STRING_SIZE];
char service[UCORE_STRING_SIZE];
setvbuf(stderr, NULL, _IONBF, 0);
fprintf(stderr, "[%s]: %s is starting!\n", EntityName, EntityName);
/**
* When using a Name Server (NS), instead of static IPC connections
* defined in init.yaml.in, the client entity foremost needs to connect with the
* Name Server kernel entity. The corresponding permissions for the Name Server must
* be defined in the psl file. Then the client entity receives the name of the server
* entity and the name of the service provided by this PictureManager entity.
*/
rc = ConnectToPictureManager(server, service);
if (rc != rcOk)
{
fprintf(
stderr,
"[%s]: Can not establish connection! "
"%s is terminating!\n",
EntityName,
EntityName);
return EXIT_FAILURE;
}
/**
* After the client entity knows the name of the PictureManager entity (server) and the name of
* the required service provided by this PictureManager entity, the client entity
* attempts to get the client IPC handle for a dynamic connection.
*/
rc = KnCmConnect(
server, service, TIMEOUT_MSEC, &handle, &rsid);
if(rc != rcOk)
{
fprintf(
stderr,
"[%s]: Error: can`t get PictureManager IPC-descriptor.\n",
EntityName);
return EXIT_FAILURE;
}
/* Initializes IPC transport for the connection with the PictureManager entity. */
NkKosTransport_Init(&transport, handle, NK_NULL, 0);
/**
* Initializes the proxy object. Every method of the proxy object will be
* implemented as a request to the server.
*/
Get_proxy_init(&proxy, &transport.base, rsid);
/* Structures of the request and response. */
Get_GetPictures_req req;
Get_GetPictures_res res;
char resBuffer[Get_GetPictures_res_arena_size];
struct nk_arena resArena = NK_ARENA_INITIALIZER(
resBuffer, resBuffer + sizeof(resBuffer));
/* Calls the server get-interface. */
if (Get_GetPictures(
&proxy.base, &req, RTL_NULL, &res, &resArena) == rcOk)
{
fprintf(
stderr,
"[%s]: Expected behavior: can get response from PictureManager. "
"Access allowed.\n",
EntityName);
PrintResponse(&res, &resArena);
}
else
{
fprintf(
stderr,
"[%s]: Error: can`t get response from PictureManager. "
"Access denied!\n",
EntityName);
return EXIT_FAILURE;
}
nk_arena_reset(&resArena);
return EXIT_SUCCESS;
}
Page top