common.h
#ifndef DEVICE_ACCESS_GENERAL_H
#define DEVICE_ACCESS_GENERAL_H
#include <stdio.h>
#include <stdlib.h>
#include <rtl/string.h>
/* Files required for transport initialization. */
#include <coresrv/nk/transport-kos.h>
#include <coresrv/sl/sl_api.h>
/**
* NK_USE_UNQUALIFIED_NAMES macro enables usage of short names,
* generated by nk compiler.
*/
#define NK_USE_UNQUALIFIED_NAMES
#define PRINT_ERR(msg) \
fprintf( \
stderr, \
"[%s][Error]: %s(), line %u: %s\n", \
EntityName, \
__func__, \
__LINE__, \
(msg))
#endif
device.c
#include "common.h"
#include <stdint.h>
/* Description of server interfaces accessed by the client entity. */
#include <device_access/ILoginManager.idl.h>
#include <device_access/IStorage.idl.h>
static const char *EntityName = "Device";
static ILoginManager_proxy iLoginManagerProxy;
static IStorage_proxy iStorageProxy;
/* Calls the Login method of the ILoginManager interface. */
static Retcode Login(const char *loginUsername)
{
Retcode retCode;
/* Request and response structures. */
struct ILoginManager_Login_req req;
char reqBuffer[ILoginManager_Login_req_arena_size];
struct nk_arena reqArena =
NK_ARENA_INITIALIZER(reqBuffer, reqBuffer + sizeof(reqBuffer));
struct ILoginManager_Login_res res;
fprintf(stderr, "[%s]: Login started...\n", EntityName);
/* Prepares the request structure. */
nk_req_reset(&req);
/* Allocates the request arena and copies the login to it. */
nk_char_t *str = nk_arena_alloc(
nk_char_t,
&reqArena,
&req.loginUsername,
rtl_strnlen(loginUsername, ILoginManager_MaxStringSize) + 1);
if (str == RTL_NULL)
{
PRINT_ERR("Can`t allocate memory in arena!");
return rcFail;
}
rtl_strncpy(str, loginUsername, ILoginManager_MaxStringSize);
/**
* Calls the device_access_ILoginManager_Login interface method.
* A request is sent to the server to call the Login method of the
* device_access_ILoginManager interface with arguments.
* The calling thread is blocked until it receives a response from
* the server.
*/
nk_err_t ret = ILoginManager_Login(
&iLoginManagerProxy.base, &req, &reqArena, &res, NULL);
if (NK_EOK == ret)
{
retCode = rcOk;
fprintf(stderr, "[%s]: Login succeeded\n", EntityName);
}
else
{
retCode = rcFail;
if (NK_ELOGIC_CHECK(ret))
{
/* This is a logical error (authentication error). */
PRINT_ERR("Invalid credentials!");
}
else
{
/* This is a transport error (denied by the KSM policy). */
PRINT_ERR("NK transport error or denied by KSM policy!");
}
}
nk_arena_reset(&reqArena);
return retCode;
}
/* Calls the Logout method of the ILoginManager interface. */
static Retcode Logout(void)
{
Retcode retCode;
/* Request and response structures. */
struct ILoginManager_Logout_req req;
struct ILoginManager_Logout_res res;
fprintf(stderr, "[%s]: Logout\n", EntityName);
/**
* Calls the device_access_LoginManager_Logout interface method.
* A request is sent to the server to call the Logout method of the
* device_access_LoginManager interface with no arguments.
* The calling thread is blocked until it receives a response from
* the server.
*/
if (NK_EOK == ILoginManager_Logout(
&iLoginManagerProxy.base, &req, NULL, &res, NULL))
{
retCode = rcOk;
}
else
{
retCode = rcFail;
PRINT_ERR("NK transport error or denied by KSM policy!");
}
return retCode;
}
/* Implements the GetInfo method of the IStorage interface. */
static Retcode GetInfo(char info[IStorage_MaxStringSize])
{
Retcode retCode;
fprintf(stderr, "[%s]: Attempt to get info...\n", EntityName);
/* Request and response structures. */
struct IStorage_GetInfo_req req;
struct IStorage_GetInfo_res res;
char resBuffer[IStorage_GetInfo_res_arena_size];
struct nk_arena resArena =
NK_ARENA_INITIALIZER(resBuffer, resBuffer + sizeof(resBuffer));
/**
* Calls the device_access_IStorage_GetInfo interface method.
* A request is sent to the server to call the GetInfo method of the
* device_access_IStorage interface with no arguments. The calling
* thread is blocked until it receives a response from the server.
*/
if (NK_EOK == IStorage_GetInfo(
&iStorageProxy.base, &req, NULL, &res, &resArena))
{
retCode = rcOk;
/* Gets the string from the response arena. */
nk_char_t *str;
nk_uint32_t slen = 0;
str = nk_arena_get(nk_char_t, &resArena, &res.info, &slen);
if (slen < 0)
{
nk_arena_reset(&resArena);
return NK_EPERM;
}
rtl_strncpy(info, str, IStorage_MaxStringSize);
fprintf(
stderr,
"[%s]: Access allowed\n"
"[%s]: Storage content: %s\n",
EntityName,
EntityName,
info);
}
else
{
retCode = rcFail;
PRINT_ERR("Access denied!");
}
nk_arena_reset(&resArena);
return retCode;
}
/* Entry point to the entity. */
int main(int argc, const char *argv[])
{
NkKosTransport loginManagerConnectionTransport;
NkKosTransport storageConnectionTransport;
if (setvbuf(stderr, RTL_NULL, _IONBF, 0))
{
PRINT_ERR("Error setting stderr parameters!");
return EXIT_FAILURE;
}
/**
* Gets the client IPC handle of the connection
* named "login_manager connection".
*/
Handle loginManagerConnectionHandle =
ServiceLocatorConnect("login_manager_connection");
if (loginManagerConnectionHandle == INVALID_HANDLE)
{
PRINT_ERR("Can`t establish static IPC login_manager_connection!");
return EXIT_FAILURE;
}
/**
* Gets the client IPC handle of the connection
* named "storage_connection".
*/
Handle storageConnectionHandle =
ServiceLocatorConnect("storage_connection");
if (storageConnectionHandle == INVALID_HANDLE)
{
PRINT_ERR("Can`t establish static IPC storage_connection!");
return EXIT_FAILURE;
}
/* Initializes IPC transport for connections to server entities. */
NkKosTransport_Init(
&loginManagerConnectionTransport,
loginManagerConnectionHandle,
NK_NULL,
0);
NkKosTransport_Init(
&storageConnectionTransport,
storageConnectionHandle,
NK_NULL,
0);
/**
* Get Runtime Interface ID (RIID) of the interface implementation
* LoginManager.loginManager.
*/
nk_iid_t loginManagerConnectionRiid = ServiceLocatorGetRiid(
loginManagerConnectionHandle,
"device_access.LoginManager.loginManager");
if (loginManagerConnectionRiid == INVALID_RIID)
{
PRINT_ERR(
"Can`t get runtime implementation ID (RIID) of "
"interface LoginManager.loginManager!");
return EXIT_FAILURE;
}
/**
* Get Runtime Interface ID (RIID) of the interface implementation
* Storage.storage.
*/
nk_iid_t storageConnectionRiid = ServiceLocatorGetRiid(
storageConnectionHandle,
"device_access.Storage.storage");
if (storageConnectionRiid == INVALID_RIID)
{
PRINT_ERR(
"Can`t get runtime implementation ID (RIID) of "
"interface Storage.storage!");
return EXIT_FAILURE;
}
/**
* Initializes proxy objects by specifying transports and server
* interface identifiers (RIIDs). Each method of the proxy object
* will be implemented as a request sent to the server.
*/
ILoginManager_proxy_init(
&iLoginManagerProxy,
&loginManagerConnectionTransport.base,
loginManagerConnectionRiid);
IStorage_proxy_init(
&iStorageProxy,
&storageConnectionTransport.base,
storageConnectionRiid);
/* Functionality testing. */
char info[IStorage_MaxStringSize];
/* Case 1. */
fprintf(
stderr,
"\n[%s]: Attempt to get info by unauthorized device\n",
EntityName);
GetInfo(info);
Logout();
/* Case 2. */
fprintf(
stderr,
"\n[%s]: Attempt to get info with invalid credentials\n",
EntityName);
Login("invalid_username");
GetInfo(info);
Logout();
/* Case 3. */
fprintf(
stderr,
"\n[%s]: Attempt to get info with valid credentials\n",
EntityName);
Login("valid_username");
GetInfo(info);
fprintf(
stderr,
"[%s]: Attempt to get info after Logout\n",
EntityName);
Logout();
GetInfo(info);
/* Case 4.*/
fprintf(
stderr,
"\n[%s]: Attempt to get info after re-login with valid credentials\n",
EntityName);
Login("valid_username");
Login("valid_username");
GetInfo(info);
Logout();
/* Case 5.*/
fprintf(
stderr,
"\n[%s]: Attempt to get info after re-login with invalid credentials\n",
EntityName);
Login("valid_username");
Login("invalid_username");
GetInfo(info);
Logout();
return EXIT_SUCCESS;
}
Page top