Annotation of libaitrpc/inc/aitrpc.h, revision 1.1

1.1     ! misho       1: /*************************************************************************
        !             2: * (C) 2010 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
        !             3: *  by Michael Pounov <misho@openbsd-bg.org>
        !             4: *
        !             5: * $Author: misho $
        !             6: * $Id: aitcli.c,v 1.2.2.17 2010/06/09 09:32:30 misho Exp $
        !             7: *
        !             8: *************************************************************************/
        !             9: #ifndef __AITRPC_H
        !            10: #define __AITRPC_H
        !            11: 
        !            12: 
        !            13: #include <assert.h>
        !            14: #include <stdlib.h>
        !            15: #include <string.h>
        !            16: #include <sys/types.h>
        !            17: #include <sys/param.h>
        !            18: #include <sys/limits.h>
        !            19: #include <sys/socket.h>
        !            20: 
        !            21: 
        !            22: #define STRSIZ                 256
        !            23: 
        !            24: #define RPC_VERSION            1
        !            25: #define RPC_DEFPORT            2611
        !            26: 
        !            27: 
        !            28: /* RPC builtin registed calls */
        !            29: 
        !            30: #define CALL_SRVCLIENTS                "rpcServerClients"
        !            31: #define CALL_SRVCALLS          "rpcServerCalls"
        !            32: #define CALL_SRVSESSIONS       "rpcServerSessions"
        !            33: 
        !            34: 
        !            35: /* RPC types */
        !            36: 
        !            37: typedef enum {
        !            38:        empty,                          // empty -> variable is not set
        !            39:        buffer, string, array,          // buffer -> uint8_t*; string -> int8_t*; array -> char**;
        !            40:        size, offset, datetime,         // size -> size_t; offset -> off_t; datetime -> time_t;
        !            41:        real, bigreal,                  // real -> float; bigreal -> double;
        !            42:        u8, u16, u32, u64,              // unsigned integers ...
        !            43:        i8, i16, i32, i64               // integers ...
        !            44: } rpc_type_t;
        !            45: 
        !            46: /* RPC value */
        !            47: 
        !            48: typedef struct {
        !            49:        rpc_type_t      val_type;
        !            50:        size_t          val_len;
        !            51:        union {
        !            52:                uint8_t         *buffer;
        !            53:                int8_t          *string;
        !            54:                int8_t          **array;
        !            55:                size_t          size;
        !            56:                off_t           offset;
        !            57:                time_t          datetime;
        !            58:                float           real;
        !            59:                double          bigreal;
        !            60:                uint8_t         u8;
        !            61:                uint16_t        u16;
        !            62:                uint32_t        u32;
        !            63:                uint64_t        u64;
        !            64:                int8_t          i8;
        !            65:                int16_t         i16;
        !            66:                int32_t         i32;
        !            67:                int64_t         i64;
        !            68:        } val;
        !            69: } __packed rpc_val_t;
        !            70: 
        !            71: #define RPC_TYPE_VAL(vl)               ((vl)->val_type)
        !            72: #define RPC_LEN_VAL(vl)                        ((vl)->val_len)
        !            73: #define RPC_EMPTY_VAL(vl)              ((vl)->val_type == empty)
        !            74: 
        !            75: #define RPC_GET_BUF(vl)                        (assert((vl)->val_type == buffer), (vl)->val.buffer)
        !            76: #define RPC_GET_STR(vl)                        (assert((vl)->val_type == string), (vl)->val.string)
        !            77: #define RPC_GET_ARRAY(vl)              (assert((vl)->val_type == array), (vl)->val.array)
        !            78: #define RPC_GET_SIZE(vl)               (assert((vl)->val_type == size), (vl)->val.size)
        !            79: #define RPC_GET_OFF(vl)                        (assert((vl)->val_type == offset), (vl)->val.offset)
        !            80: #define RPC_GET_TIME(vl)               (assert((vl)->val_type == datetime), (vl)->val.datetime)
        !            81: #define RPC_GET_REAL(vl)               (assert((vl)->val_type == real), (vl)->val.real)
        !            82: #define RPC_GET_BREAL(vl)              (assert((vl)->val_type == bigreal), (vl)->val.bigreal)
        !            83: #define RPC_GET_U8(vl)                 (assert((vl)->val_type == u8), (vl)->val.u8)
        !            84: #define RPC_GET_U16(vl)                        (assert((vl)->val_type == u16), (vl)->val.u16)
        !            85: #define RPC_GET_U32(vl)                        (assert((vl)->val_type == u32), (vl)->val.u32)
        !            86: #define RPC_GET_U64(vl)                        (assert((vl)->val_type == u64), (vl)->val.u64)
        !            87: #define RPC_GET_I8(vl)                 (assert((vl)->val_type == i8), (vl)->val.i8)
        !            88: #define RPC_GET_I16(vl)                        (assert((vl)->val_type == i16), (vl)->val.i16)
        !            89: #define RPC_GET_I32(vl)                        (assert((vl)->val_type == i32), (vl)->val.i32)
        !            90: #define RPC_GET_I64(vl)                        (assert((vl)->val_type == i64), (vl)->val.i64)
        !            91: 
        !            92: #define RPC_SET_BUF(vl, v, l)          do { rpc_val_t *val = (vl); assert(val); val->val.buffer = malloc(l); \
        !            93:                                                if (val->val.buffer) { \
        !            94:                                                        val->val_type = buffer; val->val_len = l; \
        !            95:                                                        memcpy(val->val.buffer, v, l); \
        !            96:                                                } } while (0)
        !            97: #define RPC_SET_STR(vl, v)             do { rpc_val_t *val = (vl); assert(val); val->val.string = (int8_t*) strdup(v); \
        !            98:                                                if (val->val.string) { \
        !            99:                                                        val->val_type = string; val->val_len = strlen(v) + 1; \
        !           100:                                                } } while (0)
        !           101: #define RPC_SET_ARRAY(vl, v, n, l)     do { rpc_val_t *val = (vl); assert(val); val->val.array = calloc(n, l); \
        !           102:                                                if (val->val.array) { \
        !           103:                                                        val->val_type = array; val->val_len = n * l; \
        !           104:                                                        memcpy(val->val.array, v, val->val_len); \
        !           105:                                                } } while (0)
        !           106: #define RPC_SET_SIZE(vl, v)            do { rpc_val_t *val = (vl); assert(val); val->val_type = size; val->val.size = v; \
        !           107:                                                val->val_len = sizeof(size_t); } while (0)
        !           108: #define RPC_SET_OFF(vl, v)             do { rpc_val_t *val = (vl); assert(val); val->val_type = offset; val->val.offset = v; \
        !           109:                                                val->val_len = sizeof(off_t); } while (0)
        !           110: #define RPC_SET_TIME(vl, v)            do { rpc_val_t *val = (vl); assert(val); val->val_type = datetime; val->val.datetime = v; \
        !           111:                                                val->val_len = sizeof(time_t); } while (0)
        !           112: #define RPC_SET_REAL(vl, v)            do { rpc_val_t *val = (vl); assert(val); val->val_type = real; val->val.real = v; \
        !           113:                                                val->val_len = sizeof(float); } while (0)
        !           114: #define RPC_SET_BREAL(vl, v)           do { rpc_val_t *val = (vl); assert(val); val->val_type = bigreal; val->val.bigreal = v; \
        !           115:                                                val->val_len = sizeof(double); } while (0)
        !           116: #define RPC_SET_U8(vl, v)              do { rpc_val_t *val = (vl); assert(val); val->val_type = u8; val->val.u8 = v; \
        !           117:                                                val->val_len = sizeof(uint8_t); } while (0)
        !           118: #define RPC_SET_U16(vl, v)             do { rpc_val_t *val = (vl); assert(val); val->val_type = u16; val->val.u16 = v; \
        !           119:                                                val->val_len = sizeof(uint16_t); } while (0)
        !           120: #define RPC_SET_U32(vl, v)             do { rpc_val_t *val = (vl); assert(val); val->val_type = u32; val->val.u32 = v; \
        !           121:                                                val->val_len = sizeof(uint32_t); } while (0)
        !           122: #define RPC_SET_U64(vl, v)             do { rpc_val_t *val = (vl); assert(val); val->val_type = u64; val->val.u64 = v; \
        !           123:                                                val->val_len = sizeof(uint64_t); } while (0)
        !           124: #define RPC_SET_I8(vl, v)              do { rpc_val_t *val = (vl); assert(val); val->val_type = i8; val->val.i8 = v; \
        !           125:                                                val->val_len = sizeof(int8_t); } while (0)
        !           126: #define RPC_SET_I16(vl, v)             do { rpc_val_t *val = (vl); assert(val); val->val_type = i16; val->val.i16 = v; \
        !           127:                                                val->val_len = sizeof(int16_t); } while (0)
        !           128: #define RPC_SET_I32(vl, v)             do { rpc_val_t *val = (vl); assert(val); val->val_type = i32; val->val.i32 = v; \
        !           129:                                                val->val_len = sizeof(int32_t); } while (0)
        !           130: #define RPC_SET_I64(vl, v)             do { rpc_val_t *val = (vl); assert(val); val->val_type = i64; val->val.i64 = v; \
        !           131:                                                val->val_len = sizeof(int64_t); } while (0)
        !           132: 
        !           133: #define RPC_FREE_VAL(vl)               do { rpc_val_t *val = (vl); assert(val); \
        !           134:                                                if (val->val_type == buffer && val->val.buffer) { \
        !           135:                                                        free(val->val.buffer); \
        !           136:                                                        val->val.buffer = NULL; \
        !           137:                                                } \
        !           138:                                                if (val->val_type == string && val->val.string) { \
        !           139:                                                        free(val->val.string); \
        !           140:                                                        val->val.string = NULL; \
        !           141:                                                } \
        !           142:                                                if (val->val_type == array && val->val.array) { \
        !           143:                                                        free(val->val.array); \
        !           144:                                                        val->val.array = NULL; \
        !           145:                                                } \
        !           146:                                                val->val_type = val->val_len = 0; \
        !           147:                                        } while (0)
        !           148: 
        !           149: 
        !           150: #define RPC_CALLBACK_CHECK_ARGS(f, n)  do { \
        !           151:                                                if (f->func_args != n) { \
        !           152:                                                        rpc_SetErr(22, "Error:: different number of arguments!\n"); \
        !           153:                                                        return -1; \
        !           154:                                                } \
        !           155:                                        } while(0)
        !           156: 
        !           157: 
        !           158: /* RPC session identification */
        !           159: 
        !           160: typedef struct {
        !           161:        uint8_t         sess_version;
        !           162:        uint32_t        sess_program;
        !           163:        uint32_t        sess_process;
        !           164: } __packed rpc_sess_t;
        !           165: 
        !           166: 
        !           167: /* Server managment RPC functions ... */
        !           168: 
        !           169: // RPC function registration element!
        !           170: typedef struct tagRPCFunc {
        !           171:        uint16_t                func_tag;
        !           172:        uint32_t                func_hash;
        !           173:        int8_t                  func_file[MAXPATHLEN];
        !           174:        int8_t                  func_name[UCHAR_MAX + 1];
        !           175: 
        !           176:        int8_t                  func_args;
        !           177:        rpc_val_t               *func_vals;
        !           178: 
        !           179:        struct tagRPCFunc       *func_next;
        !           180: } rpc_func_t;
        !           181: 
        !           182: 
        !           183: /* Network RPC packet - Client request */
        !           184: 
        !           185: struct tagRPCCall {
        !           186:        rpc_sess_t      call_session;
        !           187:        uint16_t        call_tag;
        !           188:        uint32_t        call_hash;
        !           189:        uint8_t         call_argc;
        !           190: } __packed;
        !           191: 
        !           192: /* Network RPC packet - Server response */
        !           193: 
        !           194: struct tagRPCRet {
        !           195:        rpc_sess_t      ret_session;
        !           196:        uint16_t        ret_tag;
        !           197:        uint32_t        ret_hash;
        !           198:        int32_t         ret_retcode;
        !           199:        int32_t         ret_errno;
        !           200:        uint8_t         ret_argc;
        !           201: } __packed;
        !           202: 
        !           203: /* Network RPC client & server elements */
        !           204: 
        !           205: typedef struct {
        !           206:        struct sockaddr cli_sa;         // host info
        !           207:        int             cli_sock;       // socket
        !           208:        pthread_t       cli_tid;        // TID of thread
        !           209: 
        !           210:        void            *cli_parent;    // pointer to parent rpc_srv_t for server or to rpc_sess_t for client
        !           211: } rpc_cli_t;
        !           212: 
        !           213: typedef struct {
        !           214:        int             srv_numcli;     // maximum concurent client connections
        !           215:        rpc_cli_t       srv_server;     // server socket
        !           216: 
        !           217:        rpc_sess_t      srv_session;    // RPC session registration info
        !           218: 
        !           219:        rpc_cli_t       *srv_clients;   // connected client sockets
        !           220: 
        !           221:        rpc_func_t      *srv_funcs;     // registered functions list
        !           222: } rpc_srv_t;
        !           223: 
        !           224: 
        !           225: typedef int (*rpc_callback_t)(void * const, rpc_func_t *, int, rpc_val_t *);
        !           226: 
        !           227: 
        !           228: // -----------------------------------------------------------------------
        !           229: 
        !           230: /* Error support functions */
        !           231: 
        !           232: // cli_GetErrno() Get error code of last operation
        !           233: inline int cli_GetErrno();
        !           234: // cli_GetError() Get error text of last operation
        !           235: inline const char *cli_GetError();
        !           236: 
        !           237: 
        !           238: /* RPC Server side functions */
        !           239: 
        !           240: /*
        !           241:  * rpc_srv_initServer() Init & create RPC Server
        !           242:  * @regProgID = ProgramID for authentication & recognition
        !           243:  * @regProcID = ProcessID for authentication & recognition
        !           244:  * @concurentClients = Concurent clients at same time to this server
        !           245:  * @family = Family socket type, AF_INET or AF_INET6
        !           246:  * @csHost = Host name or IP address for bind server, if NULL any address
        !           247:  * @Port = Port for bind server, if Port == 0 default port is selected
        !           248:  * return: NULL == error or !=NULL bind and created RPC server instance
        !           249:  */
        !           250: rpc_srv_t *rpc_srv_initServer(u_int regProgID, u_int regProcID, int concurentClients, 
        !           251:                u_short family, const char *csHost, u_short Port);
        !           252: /*
        !           253:  * rpc_srv_endServer() Destroy RPC server, close all opened sockets and free resources
        !           254:  * @srv = RPC Server instance
        !           255:  * return: none
        !           256:  */
        !           257: void rpc_srv_endServer(rpc_srv_t * __restrict srv);
        !           258: /*
        !           259:  * rpc_srv_execServer() Execute Main server loop and wait for clients requests
        !           260:  * @srv = RPC Server instance
        !           261:  * return: -1 error or 0 ok, infinite loop ...
        !           262:  */
        !           263: int rpc_srv_execServer(rpc_srv_t * __restrict srv);
        !           264: 
        !           265: /*
        !           266:  * rpc_srv_registerCall() Register call to RPC server
        !           267:  * @srv = RPC Server instance
        !           268:  * @csModule = Module name, if NULL self binary
        !           269:  * @csFunc = Function name
        !           270:  * @args = Number of function arguments
        !           271:  * return: -1 error or 0 register ok
        !           272:  */
        !           273: int rpc_srv_registerCall(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc, 
        !           274:                unsigned char args);
        !           275: /*
        !           276:  * rpc_srv_unregisterCall() Unregister call from RPC server
        !           277:  * @srv = RPC Server instance
        !           278:  * @csModule = Module name, if NULL self binary
        !           279:  * @csFunc = Function name
        !           280:  * return: -1 error, 0 not found call, 1 unregister ok
        !           281:  */
        !           282: int rpc_srv_unregisterCall(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc);
        !           283: /*
        !           284:  * rpc_srv_getFunc() Get registered call from RPC server by Name
        !           285:  * @srv = RPC Server instance
        !           286:  * @csModule = Module name, if NULL self binary
        !           287:  * @csFunc = Function name
        !           288:  * return: NULL not found call, !=NULL return call
        !           289:  */
        !           290: rpc_func_t *rpc_srv_getFunc(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc);
        !           291: /*
        !           292:  * rpc_srv_getCall() Get registered call from RPC server
        !           293:  * @srv = RPC Server instance
        !           294:  * @tag = tag for function
        !           295:  * @hash = hash for function
        !           296:  * return: NULL not found call, !=NULL return call
        !           297:  */
        !           298: inline rpc_func_t *rpc_srv_getCall(rpc_srv_t * __restrict srv, uint16_t tag, uint32_t hash);
        !           299: /*
        !           300:  * rpc_srv_execCall() Execute registered call from RPC server
        !           301:  * @data = RPC const data
        !           302:  * @call = Register RPC call
        !           303:  * @rpc = IN RPC call structure
        !           304:  * @args = IN RPC call array of rpc values
        !           305:  * return: -1 error, !=-1 ok
        !           306:  */
        !           307: int rpc_srv_execCall(void * const data, rpc_func_t * __restrict call, 
        !           308:                struct tagRPCCall * __restrict rpc, rpc_val_t * __restrict args);
        !           309: 
        !           310: 
        !           311: /*
        !           312:  * rpc_srv_declValsCall() Declare return variables for RPC call
        !           313:  * @call = RPC function call
        !           314:  * @return_vals = Number of return variables
        !           315:  * return: -1 error, !=-1 ok
        !           316:  */
        !           317: inline int rpc_srv_declValsCall(rpc_func_t * __restrict call, int return_vals);
        !           318: /*
        !           319:  * rpc_srv_freeValsCall() Free return variables for RPC call
        !           320:  * @call = RPC function call
        !           321:  * return: none
        !           322:  */
        !           323: inline void rpc_srv_freeValsCall(rpc_func_t * __restrict call);
        !           324: /*
        !           325:  * rpc_srv_copyValsCall() Copy return variables for RPC call to new variable
        !           326:  * @call = RPC function call
        !           327:  * @newvals = New allocated variables array, must be free after use
        !           328:  * return: -1 error, !=-1 Returned number of copied RPC variables
        !           329:  */
        !           330: inline int rpc_srv_copyValsCall(rpc_func_t * __restrict call, rpc_val_t ** __restrict newvals);
        !           331: /*
        !           332:  * rpc_srv_delValsCall() Clean values from return variables of RPC call
        !           333:  * @call = RPC function call
        !           334:  * return: -1 error, !=-1 Returned number of cleaned RPC variables
        !           335:  */
        !           336: inline int rpc_srv_delValsCall(rpc_func_t * __restrict call);
        !           337: /*
        !           338:  * rpc_srv_getValsCall() Get return variables for RPC call
        !           339:  * @call = RPC function call
        !           340:  * @vals = Returned variables, may be NULL
        !           341:  * return: -1 error, !=-1 Number of returned variables
        !           342:  */
        !           343: inline int rpc_srv_getValsCall(rpc_func_t * __restrict call, rpc_val_t ** __restrict vals);
        !           344: 
        !           345: 
        !           346: /* RPC Client side functions */
        !           347: 
        !           348: /*
        !           349:  * rpc_cli_openClient() Connect to RPC Server
        !           350:  * @ProgID = ProgramID for RPC session request
        !           351:  * @ProcID = ProcessID for RPC session request
        !           352:  * @family = Family socket type, AF_INET or AF_INET6
        !           353:  * @csHost = Host name or IP address for bind server
        !           354:  * @Port = Port for bind server, if Port == 0 default port is selected
        !           355:  * return: NULL == error or !=NULL connection to RPC server established
        !           356:  */
        !           357: rpc_cli_t *rpc_cli_openClient(u_int ProgID, u_int ProcID, u_short family, 
        !           358:                const char *csHost, u_short Port);
        !           359: /*
        !           360:  * rpc_cli_closeClient() Close connection to RPC server and free resources
        !           361:  * @cli = RPC Client session
        !           362:  * return: none
        !           363:  */
        !           364: void rpc_cli_closeClient(rpc_cli_t * __restrict cli);
        !           365: /*
        !           366:  * rpc_cli_execCall() Execute RPC call
        !           367:  * @cli = RPC Client session
        !           368:  * @csModule = Module name, if NULL self binary
        !           369:  * @csFunc = Function name for execute
        !           370:  * @in_argc = IN count of arguments
        !           371:  * @in_vals = IN RPC call array of rpc values
        !           372:  * @out_argc = OUT returned count of arguments
        !           373:  * @out_vals = OUT returned array of rpc values, must be free after use (see rpc_cli_freeVals())
        !           374:  * return: -1 error or != -1 ok result
        !           375:  */
        !           376: int rpc_cli_execCall(rpc_cli_t *cli, const char *csModule, const char *csFunc, int in_argc, 
        !           377:                rpc_val_t * __restrict in_vals, int *out_argc, rpc_val_t ** __restrict out_vals);
        !           378: /*
        !           379:  * rpc_cli_freeVals() Free rpc_val_t array returned from RPC call
        !           380:  * @args = Number of arguments in array
        !           381:  * @vals = Value elements
        !           382:  * return: none
        !           383:  */
        !           384: inline void rpc_cli_freeVals(int args, rpc_val_t *vals);
        !           385: 
        !           386: 
        !           387: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>