#include "global.h" /* * rpc_srv_freeValsCall() Free return variables for RPC call * @call = RPC function call * return: none */ inline void rpc_srv_freeValsCall(rpc_func_t * __restrict call) { rpc_srv_declValsCall(call, 0); } /* * rpc_srv_declValsCall() Declare return variables for RPC call * @call = RPC function call * @return_vals = Number of return variables * return: -1 error, !=-1 ok */ inline int rpc_srv_declValsCall(rpc_func_t * __restrict call, int return_vals) { void *ptr; if (!call || return_vals < 0) { rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t declare return variables for RPC call...\n"); return -1; } else call->func_args = return_vals; if (!return_vals) { if (call->func_vals) { free(call->func_vals); call->func_vals = NULL; } } else { ptr = realloc(call->func_vals, return_vals * sizeof(rpc_val_t)); if (!ptr) { LOGERR; return -1; } else call->func_vals = ptr; } return call->func_args; } /* * rpc_srv_delValsCall() Clean values from return variables of RPC call * @call = RPC function call * return: -1 error, !=-1 Returned number of cleaned RPC variables */ inline int rpc_srv_delValsCall(rpc_func_t * __restrict call) { if (!call) { rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t delete return variables ...\n"); return -1; } memset(call->func_vals, 0, call->func_args * sizeof(rpc_val_t)); return call->func_args; } /* * rpc_srv_copyValsCall() Copy return variables for RPC call to new variable * @call = RPC function call * @newvals = New allocated variables array, must be free after use * return: -1 error, !=-1 Returned number of copied RPC variables */ inline int rpc_srv_copyValsCall(rpc_func_t * __restrict call, rpc_val_t ** __restrict newvals) { if (!call || !newvals) { rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t copy return variables to new array\n"); return -1; } *newvals = calloc(call->func_args, sizeof(rpc_val_t)); if (!*newvals) { LOGERR; return -1; } else memcpy(*newvals, call->func_vals, call->func_args * sizeof(rpc_val_t)); return call->func_args; } /* * rpc_srv_getValsCall() Get return variables for RPC call * @call = RPC function call * @vals = Returned variables, may be NULL * return: -1 error, !=-1 Number of returned variables */ inline int rpc_srv_getValsCall(rpc_func_t * __restrict call, rpc_val_t ** __restrict vals) { if (!call) { rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get return variables ...\n"); return -1; } if (vals) *vals = call->func_vals; return call->func_args; } // --------------------------------------------------------- /* * rpc_srv_registerCall() Register call to RPC server * @srv = RPC Server instance * @csModule = Module name, if NULL self binary * @csFunc = Function name * @args = Number of function arguments * return: -1 error or 0 register ok */ int rpc_srv_registerCall(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc, u_char args) { rpc_func_t *func; u_char str[MAXPATHLEN + UCHAR_MAX + 1]; memset(str, 0, MAXPATHLEN + UCHAR_MAX + 1); if (!srv || !csFunc) { rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t register function to RPC server ...\n"); return -1; } if (!(func = malloc(sizeof(rpc_func_t)))) { LOGERR; return -1; } else { memset(func, 0, sizeof(rpc_func_t)); strlcpy((char*) func->func_name, csFunc, UCHAR_MAX + 1); } if (csModule) { strlcpy((char*) func->func_file, csModule, MAXPATHLEN); strlcpy((char*) str, csModule, MAXPATHLEN + UCHAR_MAX + 1); } strlcat((char*) str, "__", MAXPATHLEN + UCHAR_MAX + 1); strlcat((char*) str, csFunc, MAXPATHLEN + UCHAR_MAX + 1); func->func_tag = crcFletcher16((u_short*) str, (MAXPATHLEN + UCHAR_MAX + 1) / 2); func->func_hash = hash_fnv((char*) str, MAXPATHLEN + UCHAR_MAX + 1); if (rpc_srv_declValsCall(func, args) == -1) { free(func); return -1; } pthread_mutex_lock(&srv->srv_mtx); func->func_next = srv->srv_funcs; srv->srv_funcs = func; pthread_mutex_unlock(&srv->srv_mtx); return 0; } /* * rpc_srv_unregisterCall() Unregister call from RPC server * @srv = RPC Server instance * @csModule = Module name, if NULL self binary * @csFunc = Function name * return: -1 error, 0 not found call, 1 unregister ok */ int rpc_srv_unregisterCall(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc) { rpc_func_t func, *f, *curr; u_char str[MAXPATHLEN + UCHAR_MAX + 1]; memset(&func, 0, sizeof(rpc_func_t)); memset(str, 0, MAXPATHLEN + UCHAR_MAX + 1); if (!srv || !csFunc) { rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t unregister function from RPC server ...\n"); return -1; } else strlcpy((char*) func.func_name, csFunc, UCHAR_MAX + 1); if (csModule) { strlcpy((char*) func.func_file, csModule, MAXPATHLEN); strlcpy((char*) str, csModule, MAXPATHLEN + UCHAR_MAX + 1); } strlcat((char*) str, "__", MAXPATHLEN + UCHAR_MAX + 1); strlcat((char*) str, csFunc, MAXPATHLEN + UCHAR_MAX + 1); func.func_tag = crcFletcher16((u_short*) str, (MAXPATHLEN + UCHAR_MAX + 1) / 2); func.func_hash = hash_fnv((char*) str, MAXPATHLEN + UCHAR_MAX + 1); f = rpc_srv_getCall(srv, func.func_tag, func.func_hash); if (!f) // not found element for unregister return 0; pthread_mutex_lock(&srv->srv_mtx); if (srv->srv_funcs == f) { // if is 1st element srv->srv_funcs = srv->srv_funcs->func_next; if (f->func_args && f->func_vals) free(f->func_vals); free(f); } else { for (curr = srv->srv_funcs; curr->func_next != f; curr = curr->func_next); curr->func_next = curr->func_next->func_next; if (f->func_args && f->func_vals) free(f->func_vals); free(f); } pthread_mutex_unlock(&srv->srv_mtx); return 1; } /* * rpc_srv_getCall() Get registered call from RPC server * @srv = RPC Server instance * @tag = tag for function * @hash = hash for function * return: NULL not found call, !=NULL return call */ inline rpc_func_t * rpc_srv_getCall(rpc_srv_t * __restrict srv, uint16_t tag, uint32_t hash) { rpc_func_t *f; if (!srv) { rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get function from RPC server ...\n"); return NULL; } for (f = srv->srv_funcs; f; f = f->func_next) if (f->func_tag == tag && f->func_hash == hash) break; return f; } /* * rpc_srv_getFunc() Get registered call from RPC server by Name * @srv = RPC Server instance * @csModule = Module name, if NULL self binary * @csFunc = Function name * return: NULL not found call, !=NULL return call */ rpc_func_t * rpc_srv_getFunc(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc) { rpc_func_t func; u_char str[MAXPATHLEN + UCHAR_MAX + 1]; memset(&func, 0, sizeof(rpc_func_t)); memset(str, 0, MAXPATHLEN + UCHAR_MAX + 1); if (!srv || !csFunc) { rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get function from RPC server ...\n"); return NULL; } else strlcpy((char*) func.func_name, csFunc, UCHAR_MAX + 1); if (csModule) { strlcpy((char*) func.func_file, csModule, MAXPATHLEN); strlcpy((char*) str, csModule, MAXPATHLEN + UCHAR_MAX + 1); } strlcat((char*) str, "__", MAXPATHLEN + UCHAR_MAX + 1); strlcat((char*) str, csFunc, MAXPATHLEN + UCHAR_MAX + 1); func.func_tag = crcFletcher16((u_short*) str, (MAXPATHLEN + UCHAR_MAX + 1) / 2); func.func_hash = hash_fnv((char*) str, MAXPATHLEN + UCHAR_MAX + 1); return rpc_srv_getCall(srv, func.func_tag, func.func_hash); } // --------------------------------------------------------- /* * rpc_srv_getBLOB() Get registered BLOB * @srv = RPC Server instance * @var = hash for variable * return: NULL not found, !=NULL return blob var */ inline rpc_blob_t * rpc_srv_getBLOB(rpc_srv_t * __restrict srv, uint32_t var) { rpc_blob_t *b; if (!srv) { rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get variable from BLOB server ...\n"); return NULL; } for (b = srv->srv_blob.blobs; b; b = b->blob_next) if (b->blob_var == var) break; return b; }