Implementation of the Device entity in the Device Access example

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