diff --git a/.gitignore b/.gitignore index 5f6bec7..7f2071a 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,7 @@ _testmain.go *.test *.prof *.xml + +subprojects/rbus* +subprojects/rtMessage +subprojects/cJSON* diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b38fdbf --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,167 @@ +# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 2.8.7) + +project(cpeabs) + +include(ExternalProject) +include(CTest) + +add_definitions(-std=c99) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -g -Werror -Wall -D_GNU_SOURCE=1") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c99 -g -Werror -Wall -D_GNU_SOURCE=1") + +if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") +set(CMAKE_MACOSX_RPATH 1) +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -undefined dynamic_lookup") +endif() + +set(INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/_install) +set(PREFIX_DIR ${CMAKE_CURRENT_BINARY_DIR}/_prefix) +set(INCLUDE_DIR ${INSTALL_DIR}/include) +set(LIBRARY_DIR ${INSTALL_DIR}/lib) +set(LIBRARY_DIR64 ${INSTALL_DIR}/lib64) +set(COMMON_LIBRARY_DIR ${INSTALL_DIR}/lib/${CMAKE_LIBRARY_ARCHITECTURE}) +set(TEST_RESULTS_DIR ${CMAKE_CURRENT_BINARY_DIR}/test_results) +file(MAKE_DIRECTORY ${TEST_RESULTS_DIR}) + +include_directories(${INCLUDE_DIR} + ${INCLUDE_DIR}/cjson + ${INCLUDE_DIR}/msgpack + ${INCLUDE_DIR}/rbus + ${INCLUDE_DIR}/rbus-core + ${INCLUDE_DIR}/rtmessage + ${INCLUDE_DIR}/wdmp-c + ${INCLUDE_DIR}/cimplog + ) + +include_directories( + ${PROJECT_SOURCE_DIR}/include/cpeabs/ + ) + +if (PLATFORM STREQUAL "DEVICE_GATEWAY") +include_directories( + ${PROJECT_SOURCE_DIR}/src/rdkb/include/ + ) +elseif (PLATFORM STREQUAL "DEVICE_EXTENDER") +include_directories( + ${PROJECT_SOURCE_DIR}/src/pods/include/ + ) +endif () + +if (NOT BUILD_YOCTO) + +# msgpack-c external dependency +#------------------------------------------------------------------------------- +ExternalProject_Add(msgpack + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/msgpack + GIT_REPOSITORY https://github.com/msgpack/msgpack-c.git + GIT_TAG "7a98138f27f27290e680bf8fbf1f8d1b089bf138" + CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} + -DMSGPACK_ENABLE_CXX=OFF + -DMSGPACK_BUILD_EXAMPLES=OFF + -DBUILD_TESTING=OFF +) +add_library(libmsgpack STATIC SHARED IMPORTED) +add_dependencies(libmsgpack msgpack) + +# cimplog external dependency +#------------------------------------------------------------------------------- +ExternalProject_Add(cimplog + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/cimplog + GIT_REPOSITORY https://github.com/Comcast/cimplog.git + GIT_TAG "1.0.2" + CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} +) +add_library(libcimplog STATIC SHARED IMPORTED) +add_dependencies(libcimplog cimplog) + +# cJSON external dependency +#------------------------------------------------------------------------------- +ExternalProject_Add(cJSON + PREFIX ${PREFIX_DIR}/cJSON + GIT_REPOSITORY https://github.com/DaveGamble/cJSON.git + GIT_TAG "aafb64a1c549b7b927e339df6d35b1d5059dc235" + CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} +) +add_library(libcJSON STATIC IMPORTED) +add_dependencies(libcJSON cJSON) + +# wdmp-c external dependency +#------------------------------------------------------------------------------- +ExternalProject_Add(wdmp-c + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/wdmp-c + GIT_REPOSITORY https://github.com/Comcast/wdmp-c.git + GIT_TAG "796dddbcfa7686ec63536d950775e79b52ee5c3f" + CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} + -DBUILD_TESTING=OFF +) +add_library(libwdmp-c STATIC SHARED IMPORTED) +add_dependencies(libwdmp-c wdmp-c) + +# rtMessage external dependency +#------------------------------------------------------------------------------- +ExternalProject_Add(rtMessage + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/rtMessage + GIT_REPOSITORY https://github.com/rdkcmf/rdk-rtmessage.git + GIT_TAG rdk-next + CMAKE_ARGS += -DBUILD_RTMESSAGE_LIB=ON + -DBUILD_RTMESSAGE_SAMPLE_APP=ON + -DBUILD_FOR_DESKTOP=ON + -DBUILD_DATAPROVIDER_LIB=ON + -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DBUILD_TESTING=OFF +) +add_library(librtMessage STATIC SHARED IMPORTED) +add_dependencies(librtMessage rtMessage) + +# rbus-core external dependency +#------------------------------------------------------------------------------- +ExternalProject_Add(rbus-core + DEPENDS rtMessage + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/rbus-core + GIT_REPOSITORY https://github.com/rdkcmf/rbuscore.git + GIT_TAG rdk-next + CMAKE_ARGS += DBUILD_FOR_DESKTOP=ON -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} + -DBUILD_TESTING=OFF +) +add_library(librbus-core STATIC SHARED IMPORTED) +add_dependencies(librbus-core rbus-core) + +# rbus external dependency +#------------------------------------------------------------------------------- +ExternalProject_Add(rbus + DEPENDS rtMessage rbus-core + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/rbus + GIT_REPOSITORY https://github.com/rdkcmf/rbus.git + GIT_TAG rdk-next + CMAKE_ARGS += -DBUILD_FOR_DESKTOP=ON -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DBUILD_TESTING=OFF +) + +add_library(librbus STATIC SHARED IMPORTED) +add_dependencies(librbus rbus) + +if (PLATFORM STREQUAL "DEVICE_EXTENDER") + +# jansson external dependency +#------------------------------------------------------------------------------- +ExternalProject_Add(jansson + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/rbus + GIT_REPOSITORY https://github.com/akheron/jansson.git + GIT_TAG master + CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} +) + +add_library(libjansson STATIC SHARED IMPORTED) +add_dependencies(libjansson jansson) +endif () + +endif () + +link_directories ( ${LIBRARY_DIR} ${COMMON_LIBRARY_DIR} ${LIBRARY_DIR64} ) + +add_subdirectory(src) + +if (BUILD_TESTING) + add_subdirectory(tests) +endif (BUILD_TESTING) diff --git a/README.md b/README.md index 87ca294..a4e7aea 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,26 @@ An abstraction layer for consumer preference equipment systems. # Building and Testing Instructions +Use the below commands to build using meson ``` +./workaround.sh meson build cd build ninja all test coverage firefox meson-logs/coveragereport/index.html + +``` +Use the below commands to build using cmake +``` +Use CFLAG -DPLATFORM=DEVICE_GATEWAY to build for RDKB platform +Use CFLAG -DPLATFORM=DEVICE_EXTENDER to build for POD platform + +mkdir build +cd build +cmake .. +make +make test ``` + +The `workaround.sh` script makes it so we don't need to add the rbus stuff to the +upstream wrapdb. diff --git a/include/cpeabs/cpeabs.h b/include/cpeabs/cpeabs.h index 2bc5f73..f7e2f56 100644 --- a/include/cpeabs/cpeabs.h +++ b/include/cpeabs/cpeabs.h @@ -4,7 +4,26 @@ #ifndef __CPEABS_H__ #define __CPEABS_H__ -#include #include +#include +/*----------------------------------------------------------------------------*/ +/* Macros */ +/*----------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------*/ +/* Data Structures */ +/*----------------------------------------------------------------------------*/ +/* none */ +/*----------------------------------------------------------------------------*/ +/* External Functions */ +/*----------------------------------------------------------------------------*/ + +char * getParamValue(char *paramName); +void getValues_rbus(const char *paramName[], const unsigned int paramCount, int index, money_trace_spans *timeSpan, param_t ***paramArr, int *retValCount, WDMP_STATUS *retStatus); +int rbus_GetValueFromDB( char* paramName, char** paramValue); +int rbus_StoreValueIntoDB(char *paramName, char *value); +int rbus_waitUntilSystemReady(); +void cpeabs_free(void *ptr); #endif + diff --git a/meson.build b/meson.build index 3b74dda..e545b28 100644 --- a/meson.build +++ b/meson.build @@ -5,6 +5,7 @@ project('cpeabs', 'c', version: '0.0.0', + meson_version: '>=0.53', license: ['Apache-2.0'], default_options: ['c_std=c99', 'b_coverage=true']) @@ -15,11 +16,51 @@ if not meson.is_subproject() werror = true endif +script = join_paths(meson.source_root(), 'workaround.sh') + +r = run_command('/bin/sh', script) +if r.returncode() != 0 + message('script failed') +endif + +output = r.stdout().strip() +errortxt = r.stderr().strip() + +prefix = get_option('prefix') + +################################################################################ +# Dependencies +################################################################################ + +if meson.version().version_compare('>=0.54.0') +libcjson_dep = dependency('libcjson', version: '>=1.7.14', fallback: ['cjson']) +libcimplog_dep = dependency('libcimplog') +libwdmp_dep = dependency('libwdmp') +librtMessage_dep = dependency('librtMessage') +librbuscore_dep = dependency('librbuscore') +librbus_dep = dependency('librbus') +libjansson_dep = dependency('libjansson') +else +warning('You are running an older version of meson.') +warning('In order for dependency management to be supported you need a newer version of meson (0.54+)') +# For older versions of meson, you need to have the upstream dependencies installed +# in the correct locations. +libcjson_dep = dependency('libcjson') +libcimplog_dep = dependency('libcimplog') +libwdmp_dep = dependency('libwdmp') +librtMessage_dep = dependency('librtMessage') +librbuscore_dep = dependency('librbuscore') +librbus_dep = dependency('librbus') +libjansson_dep = dependency('libjansson') +endif + +all_dep = [libcjson_dep, librtMessage_dep, librbuscore_dep, librbus_dep, libcimplog_dep, libwdmp_dep, libjansson_dep] + ################################################################################ # Common variable definitions ################################################################################ -inc_base = 'include/'+meson.project_name() +inc_base = ['include/'+meson.project_name()] ################################################################################ # Generate the version header file @@ -27,20 +68,30 @@ inc_base = 'include/'+meson.project_name() subdir('include/'+meson.project_name()) -install_headers([headers, ver_h], subdir: meson.project_name()) +install_headers(['include/'+meson.project_name()+'/cpeabs.h', ver_h], subdir: meson.project_name()) ################################################################################ # Define the libraries ################################################################################ -inc = include_directories(inc_base) +inc = include_directories([inc_base]) +src_args = ['-lcjson', '-lpthread'] sources = ['src/common.c'] libcpeabs = library(meson.project_name(), sources, include_directories: inc, - install: true) + dependencies: all_dep, + install: true, + link_args: src_args) + +executable(meson.project_name(), + sources, + include_directories: inc, + dependencies: all_dep, + install: true, + link_args: src_args) ################################################################################ # Define the tests diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..dcdc7bc --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,37 @@ +# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +set(PROJ_CPEABS cpeabs) + +if (BUILD_YOCTO) +add_definitions(-DBUILD_YOCTO) +endif (BUILD_YOCTO) + +if (PLATFORM STREQUAL "DEVICE_GATEWAY") +add_definitions(-DDEVICE_GATEWAY) +elseif (PLATFORM STREQUAL "DEVICE_EXTENDER") +add_definitions(-DDEVICE_EXTENDER) +endif () + +if (PLATFORM STREQUAL "DEVICE_GATEWAY") +set(SOURCES rdkb/impl.c common.c) +set(HEADERS ${PROJECT_SOURCE_DIR}/include/cpeabs/cpeabs.h ${PROJECT_SOURCE_DIR}/src/rdkb/include/cpeabs_rdkb.h) +elseif (PLATFORM STREQUAL "DEVICE_EXTENDER") +set(SOURCES pods/impl.c pods/cpeabs_ovsdb_utils.c common.c) +set(HEADERS ${PROJECT_SOURCE_DIR}/include/cpeabs/cpeabs.h ${PROJECT_SOURCE_DIR}/src/pods/include/cpeabs_ovsdb_utils.h ${PROJECT_SOURCE_DIR}/src/pods/include/cpeabs_pod.h) +add_definitions(-DPS_FILE_PATH=${PS_FILE_PATH}) +else () +set(SOURCES pc/impl.c common.c) +endif () + +#Support cpeabs lib for backward compatibility +add_library(${PROJ_CPEABS} STATIC ${HEADERS} ${SOURCES}) +add_library(${PROJ_CPEABS}.shared SHARED ${HEADERS} ${SOURCES}) +set_target_properties(${PROJ_CPEABS}.shared PROPERTIES OUTPUT_NAME ${PROJ_CPEABS}) +set_property(TARGET ${PROJ_CPEABS} PROPERTY C_STANDARD 99) +set_property(TARGET ${PROJ_CPEABS}.shared PROPERTY C_STANDARD 99) + +install (TARGETS ${PROJ_CPEABS} DESTINATION lib${LIB_SUFFIX}) +install (TARGETS ${PROJ_CPEABS}.shared DESTINATION lib${LIB_SUFFIX}) +install (FILES ${HEADERS} DESTINATION include/${PROJ_CPEABS}) + diff --git a/src/common.c b/src/common.c index c571421..59132ca 100644 --- a/src/common.c +++ b/src/common.c @@ -3,8 +3,9 @@ #include #include +#include #include - +#include /*----------------------------------------------------------------------------*/ /* Macros */ /*----------------------------------------------------------------------------*/ @@ -23,8 +24,7 @@ /*----------------------------------------------------------------------------*/ /* Function Prototypes */ /*----------------------------------------------------------------------------*/ -/* none */ - +void do_something(); /*----------------------------------------------------------------------------*/ /* Internal functions */ /*----------------------------------------------------------------------------*/ @@ -33,7 +33,28 @@ /*----------------------------------------------------------------------------*/ /* External Functions */ /*----------------------------------------------------------------------------*/ +//For test purpose void do_something() { printf("I do something well.\n"); } + +//For meson build stub function +int main() +{ + return 0; +} + +//User-defined function to free pointer +void cpeabs_free(void *ptr) +{ + if(ptr != NULL) + { + free((void*)(ptr)); + ptr = NULL; + } + else + { + printf("Trying to free null pointer\n"); + } +} diff --git a/src/pc/impl.c b/src/pc/impl.c new file mode 100644 index 0000000..aa2162c --- /dev/null +++ b/src/pc/impl.c @@ -0,0 +1,71 @@ +/* SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cpeabs.h" +/*----------------------------------------------------------------------------*/ +/* Macros */ +/*----------------------------------------------------------------------------*/ +#define UNUSED(x) (void )(x) +/*----------------------------------------------------------------------------*/ +/* Data Structures */ +/*----------------------------------------------------------------------------*/ +/* none */ +/*----------------------------------------------------------------------------*/ +/* File Scoped Variables */ +/*----------------------------------------------------------------------------*/ +/* none */ +/*----------------------------------------------------------------------------*/ +/* Function Prototypes */ +/*----------------------------------------------------------------------------*/ +/* none */ +/*----------------------------------------------------------------------------*/ +/* External Functions */ +/*----------------------------------------------------------------------------*/ +char * getParamValue(char *paramName) +{ + UNUSED(paramName); + return NULL; +} + +/** + * To persist TR181 parameter values in DB. + */ +int rbus_StoreValueIntoDB(char *paramName, char *value) +{ + UNUSED(paramName); + UNUSED(value); + return 1; +} + +/** + * To fetch TR181 parameter values from DB. + */ +int rbus_GetValueFromDB( char* paramName, char** paramValue) +{ + UNUSED(paramName); + UNUSED(paramValue); + return 1; +} + +void getValues_rbus(const char *paramName[], const unsigned int paramCount, int index, money_trace_spans *timeSpan, param_t ***paramArr, int *retValCount, WDMP_STATUS *retStatus) +{ + UNUSED(paramName); + UNUSED(paramCount); + UNUSED(index); + UNUSED(timeSpan); + UNUSED(paramArr); + UNUSED(retValCount); + UNUSED(retStatus); + return; +} + diff --git a/src/pods/cpeabs_ovsdb_utils.c b/src/pods/cpeabs_ovsdb_utils.c new file mode 100644 index 0000000..f9c1c52 --- /dev/null +++ b/src/pods/cpeabs_ovsdb_utils.c @@ -0,0 +1,625 @@ +/* SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cpeabs_ovsdb_utils.h" +#include "cpeabs.h" +#include "cpeabs_pod.h" + +static int g_ovsdb_handle = -1; +static char ovsdb_opt_db[32] = "Open_vSwitch"; +static int ovsdb_where_num = 0; +static char **ovsdb_where_expr = NULL; + +int ovsdb_connect(void); +void ovsdb_close(int fd); +static json_t *ovsdb_json_exec(char *method, json_t *params); +static bool ovsdb_json_error(json_t *jres); +static bool ovsdb_parse_columns(json_t *columns, int colc, char *colv[]); +json_t *json_value(char *str); + +/* + * Initialize Ovsdb connection and return handle. + */ +int ovsdb_util_init() +{ + int db = -1; + + db = ovsdb_connect(); + if (db < 0) { + WebcfgError("%s : Failed to connect to ovsdb. \n",__func__); + } + else + { + WebcfgError("%s : Successfully connected to ovsdb \n",__func__); + g_ovsdb_handle = db; + } + return db; +} + +bool ovsdb_util_fini() +{ + if (g_ovsdb_handle > 0) + { + ovsdb_close(g_ovsdb_handle); + g_ovsdb_handle = -1; + } + return true; +} + +int ovsdb_handle_get() +{ + return g_ovsdb_handle; +} + +/* + * =========================================================================== + * OVSDB communication functions + * =========================================================================== + */ + +/* + * Connect to a OVSDB database + */ +int ovsdb_connect(void) +{ + struct sockaddr_un addr; + + int fd = -1; + + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) + { + WebcfgError("Unable to open OVSDB socket: %s\n", strerror(errno)); + goto error; + } + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + + char *sock_path = OVSDB_SOCK_PATH; + + if (strlen(sock_path) >= sizeof(addr.sun_path)) + { + WebcfgError("Connect path too long!\n"); + goto error; + } + cpeabStrncpy(addr.sun_path, sock_path, sizeof(addr.sun_path)); + + if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) + { + WebcfgError("Unable to connect to OVSDB: %s\n", strerror(errno)); + goto error; + } + + return fd; + +error: + if (fd >= 0) close(fd); + + return -1; +} + +void ovsdb_close(int fd) +{ + close(fd); +} + +/* + * OVSDB Select method + */ +bool ovsdb_select(char *table, json_t *where, int coln, char *colv[], + json_t **jresult, json_t **acolumns) +{ + *jresult = NULL; + json_t *columns = json_array(); + *acolumns = columns; + + json_t *jparam = json_pack("[ s, { s:s, s:s, s:o } ]", + ovsdb_opt_db, + "op", "select", + "table", table, + "where", where); + if (jparam == NULL) + { + WebcfgError("Error creating JSON-RPC parameters (SELECT).\n"); + return false; + } + if (coln > 0) + { + /* Parse columns */ + if (!ovsdb_parse_columns(columns, coln, colv)) + { + WebcfgError("Error parsing columns. \n"); + } + + if (json_object_set_new(json_array_get(jparam, 1), "columns", columns) != 0) + { + WebcfgError("Error appending columns.\n"); + return false; + } + } + json_t *jres = ovsdb_json_exec("transact", jparam); + if (!ovsdb_json_error(jres)) + { + return false; + } + *jresult = jres; + return true; +} + +/* + * This functions splits a string into a left value, an operator and a right value. It can be used to + * parse structures as a=b, or a!=b etc. + * + * This function modifies the string expr + * Param op is taken from the "delim" array + */ +static bool str_parse_expr(char *expr, char *delim[], char **lval, char **op, char **rval) +{ + char *pop; + char **pdelim; + + for (pdelim = delim; *pdelim != NULL; pdelim++) + { + /* Find the delimiter string */ + pop = strstr(expr, *pdelim); + if (pop == NULL) continue; + + *op = *pdelim; + + *lval = expr; + *rval = pop + strlen(*pdelim); + *pop = '\0'; + + return true; + } + + /* Error parsing */ + return false; +} + + +/* + * Check if an error was reported from OVSDB, if so, display it and return false. Return true otherwise. + */ +bool ovsdb_json_error(json_t *jobj) +{ + json_t *jres = json_object_get(jobj, "result"); + if (jres == NULL) + { + WebcfgError("Error: No \"result\" object is present.\n"); + return false; + } + + /* Use the first object in the array */ + jres = json_array_get(jres, 0); + + json_t *jerror = json_object_get(jres, "error"); + if (jerror == NULL) + { + /* No error, return */ + return true; + } + WebcfgError("Error: %s\n", json_string_value(jerror)); + + json_t *jdetails = json_object_get(jres, "details"); + if (jdetails != NULL) + { + WebcfgError("Details: %s\n", json_string_value(jdetails)); + } + + json_t *jsyntax = json_object_get(jres, "syntax"); + if (jsyntax != NULL) + { + WebcfgError("Syntax: %s\n", json_string_value(jsyntax)); + } + + return false; +} + +/* + * Return true if string is encased in quotation marks, either ' or " + */ +bool str_is_quoted(char *str) +{ + size_t len = strlen(str); + + if ((str[0] == '"' && str[len - 1] == '"') || + (str[0] == '\'' && str[len - 1] == '\'')) + { + return true; + } + + return false; +} + +/* + * Guess the type of "str" and return a JSON object of the corresponding type. + * + * If str is: + * "\"...\"" -> Everything that starts with a quote and ends in a quote is assumed to be a string. + * The resulting object is the value without quotes + * "true" -> bool, value set to true + * "false" -> bool, value set to false + * "XXXX" -> where X are digits only -> integer + * ["map", -> object + * ["set", -> object + * ["uuid", -> object + * + * Everything else is assumed to be a string. + */ +json_t *json_value(char *str) +{ + if (str[0] == '\0') return json_string(""); + + /* + * Check for quoted string first + */ + if (str_is_quoted(str)) + { + return json_stringn(str + 1, strlen(str) - 2); + } + + if (strcmp(str, "true") == 0) + { + return json_true(); + } + else if (strcmp(str, "false") == 0) + { + return json_false(); + } + + /* + * Try to convert it to an integer + */ + char *pend; + json_int_t lval = strtoll(str, &pend, 0); + + /* All character were consumed during conversion -- it's an int */ + if (*pend == '\0') + { + return json_integer(lval); + } + // check if object + char *str_map = "[\"map\","; + char *str_set = "[\"set\","; + char *str_uuid = "[\"uuid\","; + if (!strncmp(str, str_map, strlen(str_map)) + || !strncmp(str, str_set, strlen(str_set)) + || !strncmp(str, str_uuid, strlen(str_uuid))) + { + // Try to parse rval as a json object + json_t *jobj = json_loads(str, 0, NULL); + if (jobj) { + return jobj; + } + WebcfgError("Error decoding as object value: %s\n", str); + // fallthrough, treat as string for backward compatibility, eventually treat as error + } + + /* Everything else is a string */ + return json_string(str); +} + +/* + * Parse a list of columns, generate an array object out of it + */ +static bool ovsdb_parse_columns(json_t *columns, int colc, char *colv[]) +{ + int ii; + + json_t *jrval = NULL; + + for (ii = 0; ii < colc; ii++) + { + char col[OVSDB_COL_STR]; + + /* + * Use only the "left" value of an expression + */ + char *lval, *op, *rval; + + static char *delim[] = + { + ":=", + "::", + "~=", + NULL + }; + + if (strlen(colv[ii]) + 1 > sizeof(col)) + { + WebcfgError("Column too big: %s\n", colv[ii]); + return false; + } + cpeabStrncpy(col, colv[ii], OVSDB_COL_STR); + if (!str_parse_expr(col, delim, &lval, &op, &rval)) + { + /*Not an expression, use whole line as left value */ + lval = colv[ii]; + rval = NULL; + } + else + { + /* Depending on the operator, do different things with rval */ + if (strcmp(op, ":=") == 0) + { + /* := standard right value processing */ + jrval = json_value(rval); + } + else if (strcmp(op, "::") == 0) + { + /* Try to parse rval as a json object */ + jrval = json_loads(rval, 0, NULL); + if (jrval == NULL) + { + WebcfgError("Error decoding column right value: %s\n", rval); + return false; + } + } + else if (strcmp(op, "~=") == 0) + { + /* Force right value to string */ + jrval = json_string(rval); + } + else + { + WebcfgError("Error decoding column operator: %s\n", op); + return false; + } + } + + if (json_is_array(columns)) + { + /* Append left value only */ + if (json_array_append_new(columns, json_string(lval)) != 0) + { + goto error; + } + } + else if (json_is_object(columns) && rval != NULL) + { + if (json_object_set_new(columns, lval, jrval) != 0) + { + goto error; + } + } + else + { + WebcfgError("Parameter is not an object or array.\n"); + goto error; + } + + jrval = NULL; + } + return true; + +error: + if (jrval != NULL) json_decref(jrval); + return false; +} + +bool ovsdb_json_get_result_rows(json_t *jobj, json_t **jrows) +{ + *jrows = NULL; + + json_t *jres = json_object_get(jobj, "result"); + if (jres == NULL) + { + WebcfgError("Error: No \"result\" object is present.\n"); + return false; + } + + /* Use the first object in the array */ + jres = json_array_get(jres, 0); + if (jres == NULL) + { + WebcfgError("Unexpected JSON result: Got empty array.\n"); + return false; + } + + *jrows = json_object_get(jres, "rows"); + if (*jrows == NULL) + { + WebcfgError("Error: Expected \"rows\" object in response.\n"); + return false; + } + return true; +} + +/* + * Execute a JSON RPC command, close the connection and return + */ +json_t *ovsdb_json_exec(char *method, json_t *params) +{ + char buf[2048]; + + char *str = NULL; + json_t *jres = NULL; + int db = -1; + + json_t *jexec = json_pack("{ s:s, s:o, s:i }", "method", method, "params", params, "id", getpid()); + + str = json_dumps(jexec, 0); + WebcfgDebug(">>>>>>> %s\n", str); + db = g_ovsdb_handle; + + ssize_t len = strlen(str); + if (write(db, str, len) < len) + { + WebcfgError("Error writing to OVSDB: %s\n", strerror(errno)); + goto error; + } + + ssize_t nrd; + nrd = read(db, buf, sizeof(buf)); + if (nrd < 0) + { + goto error; + } + + buf[nrd] = '\0'; + + WebcfgDebug("<<<<<<< %s\n", buf); + + jres = json_loads(buf, JSON_PRESERVE_ORDER, NULL); + +error: + if (str != NULL) free(str); + if (db > 0) ovsdb_close(db); + + return jres; +} + +bool ovsdb_parse_where(json_t *where, char *_str, bool is_parent_where) +{ + bool retval = false; + char str[OVSDB_COL_STR]; + + if (strlen(_str) + 1 > sizeof(str)) + { + /* String too long */ + return false; + } + + cpeabStrncpy(str, _str, sizeof(str)); + + static char *where_delims[] = + { + "==", + "!=", + ":inc:", + ":exc:", + NULL, + }; + + char *lval, *op, *rval; + if (!str_parse_expr(str, where_delims, &lval, &op, &rval)) + { + WebcfgError("Error parsing expression: %s\n", _str); + return false; + } + + /* Convert ovsh opt o ovsdb op */ + if (strcmp(op, ":inc:") == 0) + { + op = "includes"; + } + else if (strcmp(op, ":exc:") == 0) + { + op = "excludes"; + } + else + { + /* Other ovsh operators (where_delims) match 1:1 to ovsdb operators */ + } + + /* + * Create a JSON array from values + */ + json_t *jop = json_array(); + if (jop == NULL) + { + WebcfgError("Unable to create JSON array\n"); + return false; + } + + if (json_array_append_new(jop, json_string(lval)) != 0) + { + WebcfgError("Unable to append JSON array (lval)\n"); + goto error; + } + + if (json_array_append_new(jop, json_string(op)) != 0) + { + WebcfgError("Unable to append JSON array (op)\n"); + goto error; + } + + if (json_array_append_new(jop, json_value(rval)) != 0) + { + WebcfgError("Unable to append JSON array (rval)\n"); + goto error; + } + + if (json_array_append(where, jop) != 0) + { + WebcfgError("Unable to append JSON array (where)\n"); + goto error; + } + + retval = true; + + /* Append to global where expr table, but only if this is a regular where + * statement (not part of a --parent argument) */ + if (!is_parent_where) + { + ovsdb_where_num++; + ovsdb_where_expr = (char**)realloc(ovsdb_where_expr, sizeof(char**) * ovsdb_where_num); + ovsdb_where_expr[ovsdb_where_num-1] = strdup(_str); + } + +error: + if (jop != NULL) json_decref(jop); + + return retval; +} + +bool ovsdb_string_value_get(char *table,json_t *where, int coln, char * colv[],char *result_str, unsigned int len ) + +{ + int handle = -1; + bool ret = false; + json_t *jres = NULL; + json_t *columns = NULL; + json_t *jrows = NULL; + json_t *result = NULL; + + handle = ovsdb_util_init(); + if (handle < 0) { + goto exit; + } + if (!ovsdb_select(table, where, coln, colv, &jres, &columns)) { + WebcfgError("ovsdb_select failed.\n"); + goto exit; + } + if (!ovsdb_json_get_result_rows(jres, &jrows)) { + WebcfgError("ovsdb_json_get_result_rows failed.\n"); + goto exit; + } + + if (jrows != NULL || (json_array_size(jrows) > 0)) { + result = json_object_get(json_array_get(jrows,0),colv[0]); + if (result) + { + if (json_is_string(result)) { + cpeabStrncpy(result_str,json_string_value(result),len); + ret = true; + } else if (json_is_integer(result)) { + snprintf(result_str,len, "%lld",json_integer_value(result)); + ret = true; + } else { + WebcfgError(" Un supported value type.\n"); + } + } + else { + WebcfgError("JROWS is null or Json Array size is less than 0\n"); + } + } +exit : + ovsdb_util_fini(); + return ret; +} diff --git a/src/pods/impl.c b/src/pods/impl.c new file mode 100644 index 0000000..b9a0505 --- /dev/null +++ b/src/pods/impl.c @@ -0,0 +1,687 @@ +/* SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include +#include +#include +#include "cpeabs.h" +#include "cpeabs_ovsdb_utils.h" +#include "cpeabs_pod.h" + +#define BFR_SIZE_16 16 +#define BFR_SIZE_32 32 +#define BFR_SIZE_64 64 +#define BFR_SIZE_128 128 +#define BFR_SIZE_256 256 + +#define ACCOUNT_FILE "account" +#define WEBCFG_CFG_FILE "webcfg.json" + +#define MAKE_STR(x) _MAKE_STR(x) +#define _MAKE_STR(x) #x + +#define OSP_PSTORE_ACCOUNT MAKE_STR(PS_FILE_PATH) ACCOUNT_FILE +#define WEBCONFIG_CONFIG_PS_FILE MAKE_STR(PS_FILE_PATH) WEBCFG_CFG_FILE + +#define OSP_PSTORE_REBOOT "/var/run/osp_reboot_reason" +#define WEBCFG_RFC_PARAM "Device.X_RDK_WebConfig.RfcEnable" +#define PARAM_RFC_ENABLE "eRT.com.cisco.spvtg.ccsp.webpa.WebConfigRfcEnable" +#define WEBCFG_URL_PARAM "Device.X_RDK_WebConfig.URL" +#define WEBCFG_SUPPLEMENTARY_TELEMETRY_PARAM "Device.X_RDK_WebConfig.SupplementaryServiceUrls.Telemetry" + +#define WEBCFG_MAX_PARAM_LEN 128 +#define RETURN_OK 0 +#define RETURN_ERR -1 + +/*----------------------------------------------------------------------------*/ +char deviceMAC[BFR_SIZE_64]; +/*----------------------------------------------------------------------------*/ +/* Function Prototypes */ +/*----------------------------------------------------------------------------*/ +void macIDToLower(char macValue[],char macConverted[]); +/*----------------------------------------------------------------------------*/ +/* Macros */ +/*----------------------------------------------------------------------------*/ +void cpeabStrncpy(char *destStr, const char *srcStr, size_t destSize) +{ + strncpy(destStr, srcStr, destSize-1); + destStr[destSize-1] = '\0'; +} + +bool json_string_value_get(char *key, char* value_str, size_t len) +{ + json_t *json; + json_error_t error; + json_t *value; + bool ret = false; + + json = json_load_file(WEBCONFIG_CONFIG_PS_FILE, 0, &error); + if(!json) + { + WebcfgError("Failed to load %s",WEBCONFIG_CONFIG_PS_FILE); + return ret; + } + + value = json_object_get(json, key); + if (value) + { + cpeabStrncpy(value_str,json_string_value(value),len); + WebcfgInfo("%s : Fetched [%s] = [%s]. \n",__func__,key,value_str); + ret = true; + } + else + { + WebcfgError("Json value is Null.\n"); + } + json_decref(json); + return ret; +} + +bool json_string_value_set(char *key, char* value_str) +{ + json_t *json; + json_error_t error; + json_t *value_json; + bool ret = false; + + json = json_load_file(WEBCONFIG_CONFIG_PS_FILE, 0, &error); + if(!json) + { + WebcfgError("Failed to load %s",WEBCONFIG_CONFIG_PS_FILE); + return ret; + } + + value_json = json_string(value_str); + + if (json_object_set(json, key, value_json) == RETURN_OK) + { + WebcfgInfo("%s : Successfully set : [%s] = [%s] \n",__func__,key,value_str); + if (json_dump_file(json,WEBCONFIG_CONFIG_PS_FILE,0) == RETURN_OK ) + { + WebcfgInfo("Successfully Written to file. \n"); + ret = true; + } + } + else + { + WebcfgError("Json value is Null.\n"); + } + json_decref(value_json); + json_decref(json); + return ret; +} + +void macIDToLower(char macValue[],char macConverted[]) +{ + int i = 0; + int j; + char *token[BFR_SIZE_64]; + char tmp[BFR_SIZE_64]; + + cpeabStrncpy(tmp, macValue,sizeof(tmp)); + token[i] = strtok(tmp, ":"); + if(token[i]!=NULL) + { + cpeabStrncpy(macConverted, token[i],BFR_SIZE_64); + i++; + } + while ((token[i] = strtok(NULL, ":")) != NULL) + { + strncat(macConverted, token[i], 63); + macConverted[63]='\0'; + i++; + } + macConverted[63]='\0'; + for(j = 0; macConverted[j]; j++) + { + macConverted[j] = tolower(macConverted[j]); + } +} + +char* get_deviceMAC() +{ + if(strlen(deviceMAC) != 0) + { + WebcfgDebug("deviceMAC returned %s\n", deviceMAC); + return deviceMAC; + } + + json_t *where = json_array(); + char *table = "Wifi_Inet_State"; + char *colv[] = {"hwaddr"}; + char buff[BFR_SIZE_64]; + char *where_str = "if_name==eth0"; + + if (!ovsdb_parse_where(where,where_str, false)) + { + WebcfgError("Error parsing WHERE statement: %s",where_str); + } + memset(deviceMAC,0,sizeof(deviceMAC)); + memset(buff,0,sizeof(buff)); + WebcfgDebug("Reaching after memset of buff inside get devicemac\n"); + if (ovsdb_string_value_get(table,where,1,colv,buff,sizeof(buff))) + { + WebcfgDebug("Reaching after ovsdb_string_value_get success inside get devicemac\n"); + macIDToLower(buff, deviceMAC); + WebcfgDebug("deviceMAC returned from lib in converted format is: %s\n",deviceMAC); + return deviceMAC; + } + else + { + WebcfgError("Failed to GetValue for deviceMAC\n"); + return NULL; + } +} + +char * getSerialNumber() +{ + json_t *where = json_array(); + char *table = "AWLAN_Node"; + char *colv[] = {"serial_number"}; + char buff[BFR_SIZE_64]; + char *serialNum = NULL; + + serialNum = malloc(BFR_SIZE_64*sizeof(char)); + if (!serialNum) + { + WebcfgError("%s : serialNum couldnt be assigned with memory\n",__func__); + return NULL; + } + + memset(buff,0,sizeof(buff)); + + if (ovsdb_string_value_get(table,where,1,colv,buff,sizeof(buff))) + { + WebcfgDebug("serialNum returned from lib is %s\n", buff); + cpeabStrncpy(serialNum,buff,BFR_SIZE_64*sizeof(char)); + return serialNum; + } + else + { + WebcfgError("Failed to GetValue for serialNum\n"); + cpeabs_free(serialNum); + return NULL; + } +} + +char * getDeviceBootTime() +{ + json_t *where = json_array(); + char *table = "AWLAN_Node"; + char *colv[] = {"boot_time"}; + char buff[BFR_SIZE_64]; + char *bootTime = NULL; + + bootTime = malloc(BFR_SIZE_64*sizeof(char)); + if (!bootTime) + { + WebcfgError("%s : bootTime couldnt be assigned with memory\n",__func__); + return NULL; + } + + memset(buff,0,sizeof(buff)); + + if (ovsdb_string_value_get(table,where,1,colv,buff,sizeof(buff))) + { + WebcfgDebug("bootTime returned from lib is %s\n", buff); + cpeabStrncpy(bootTime,buff,BFR_SIZE_64*sizeof(char)); + return bootTime; + } + else + { + WebcfgError("Failed to GetValue for bootTime\n"); + cpeabs_free(bootTime); + return NULL; + } +} + +char * getProductClass() +{ + char *productClass = NULL; + productClass = malloc(BFR_SIZE_16*sizeof(char)); + if (!productClass) + { + WebcfgError("%s : productClass couldnt be assigned with memory\n",__func__); + return NULL; + } + cpeabStrncpy(productClass,"XE2",BFR_SIZE_16*sizeof(char)); + return productClass; +} + +char * getModelName() +{ + json_t *where = json_array(); + char *table = "AWLAN_Node"; + char *colv[] = {"model"}; + char buff[BFR_SIZE_64]; + char *modelName = NULL; + + modelName = malloc(BFR_SIZE_64*sizeof(char)); + if (!modelName) + { + WebcfgError("%s : modelName couldnt be assigned with memory\n",__func__); + return NULL; + } + + memset(buff,0,sizeof(buff)); + + if (ovsdb_string_value_get(table,where,1,colv,buff,sizeof(buff))) + { + WebcfgDebug("modelName returned from lib is %s\n", buff); + cpeabStrncpy(modelName,buff,BFR_SIZE_64*sizeof(char)); + return modelName; + } + else + { + WebcfgError("Failed to GetValue for modelName\n"); + cpeabs_free(modelName); + return NULL; + } +} + +char * getFirmwareVersion() +{ + json_t *where = json_array(); + char *table = "AWLAN_Node"; + char *colv[] = {"firmware_version"}; + char buff[BFR_SIZE_64]; + char *firmware_version = NULL; + + firmware_version = malloc(BFR_SIZE_64*sizeof(char)); + if (!firmware_version) + { + WebcfgError("%s : firmware_version couldnt be assigned with memory\n",__func__); + return NULL; + } + + memset(buff,0,sizeof(buff)); + + if (ovsdb_string_value_get(table,where,1,colv,buff,sizeof(buff))) + { + WebcfgDebug("firmwareVersion returned from lib is %s\n", buff); + cpeabStrncpy(firmware_version,buff,BFR_SIZE_64*sizeof(char)); + return firmware_version; + } + else + { + WebcfgError("Failed to GetValue for firmwareVersion\n"); + cpeabs_free(firmware_version); + return NULL; + } +} + +char * getConnClientParamName() +{ + return NULL; +} + +char * getRebootReason() +{ + FILE *rebptr = NULL; + char reboot_type[BFR_SIZE_64]; + char reboot_str[BFR_SIZE_32]; + char reboot_osprsn[BFR_SIZE_128]; + char reboot_fileresp[BFR_SIZE_256]; + char * reboot_reason = NULL; + + reboot_reason = malloc(BFR_SIZE_64*sizeof(char)); + if (!reboot_reason) + { + WebcfgError("%s : reboot_reason couldnt be assigned with memory\n",__func__); + return NULL; + } + + memset(reboot_type,0,sizeof(reboot_type)); + memset(reboot_str,0,sizeof(reboot_str)); + memset(reboot_fileresp, 0, sizeof(reboot_fileresp)); + memset(reboot_osprsn, 0, sizeof(reboot_osprsn)); + if ((rebptr = fopen(OSP_PSTORE_REBOOT, "r")) == NULL) + { + WebcfgError("Error! File %s cannot be opened.\n", OSP_PSTORE_REBOOT); + cpeabs_free(reboot_reason); + return NULL; + } + if( fgets(reboot_fileresp, sizeof(reboot_fileresp), rebptr) != NULL ) + { + sscanf(reboot_fileresp, "%31s %63s %127[^\n]", reboot_str, reboot_type, reboot_osprsn); + } + else + { + WebcfgError("Error! Output from file %s couldnt be parsed.", OSP_PSTORE_REBOOT); + cpeabs_free(reboot_reason); + return NULL; + } + cpeabStrncpy(reboot_reason,reboot_type,BFR_SIZE_64*sizeof(char)); + if (strlen(reboot_reason) > 0) + { + WebcfgDebug("Reboot reason returned from lib is %s\n", reboot_reason); + return reboot_reason; + } + else + { + WebcfgError("Failed to GetValue for reboot_reason\n"); + cpeabs_free(reboot_reason); + return NULL; + } +} + +char * cutting_delimiters(char *pstore_content, char * PATTERN1, char *PATTERN2) +{ + char *start, *end; + char *target = NULL; + if((start = strstr(pstore_content, PATTERN1))) + { + start += strlen(PATTERN1); + if ((end = strstr(start, PATTERN2))) + { + target = (char *)malloc(end-start+1); + memcpy(target,start,end-start); + target[end-start] = '\0'; + } + } + return target; +} + +char * get_id_pstore(int id_chk, char *id_type) +{ + char pstore_content[BFR_SIZE_256]; + char acc_id[BFR_SIZE_64]; + char partner_id[BFR_SIZE_64]; + char *acc_id_ret = NULL; + char *partner_id_ret = NULL; + FILE *fptr = NULL; + + id_type = malloc(BFR_SIZE_64*sizeof(char)); + + if (!id_type) + { + WebcfgError("%s : id_type couldnt be assigned with memory\n",__func__); + return NULL; + } + if ((fptr = fopen(OSP_PSTORE_ACCOUNT, "r")) == NULL) + { + WebcfgError("Error! File %s cannot be opened.",OSP_PSTORE_ACCOUNT); + cpeabs_free(id_type); + return NULL; + } + memset(pstore_content,0,sizeof(pstore_content)); + fscanf(fptr, "%[^\n]", pstore_content); + WebcfgDebug("Data from the file:\n%s\n", pstore_content); + fclose(fptr); + + memset(acc_id,0,sizeof(acc_id)); + memset(partner_id,0,sizeof(partner_id)); + + if((strchr(pstore_content, ',') != NULL) && (strlen(pstore_content) > 0)) + { + sscanf(pstore_content, "%*[^:]%*c%[^,]%*[^:]%*c%[^}]", acc_id, partner_id); + acc_id_ret = cutting_delimiters(acc_id, "\"", "\""); + partner_id_ret = cutting_delimiters(partner_id, "\"", "\""); + } + else if(strlen(pstore_content) > 0) + { + sscanf(pstore_content, "%*[^:]%*c%[^}]", acc_id); + acc_id_ret = cutting_delimiters(acc_id, "\"", "\""); + } + else + { + WebcfgError("Error!The file is present but is empty!\n"); + cpeabs_free(id_type); + return NULL; + } + if ((id_chk == 1) && (strlen(partner_id) > 0)) + { + cpeabStrncpy(id_type,partner_id_ret,BFR_SIZE_64*sizeof(char)); + return id_type; + } + + if ((id_chk == 0) && (strlen(acc_id) > 0)) + { + cpeabStrncpy(id_type,acc_id_ret,BFR_SIZE_64*sizeof(char)); + return id_type; + } + + WebcfgError("Error! Partnerid or/and Accountid couldnt be parsed"); + cpeabs_free(id_type); + return NULL; +} +char * getPartnerID() +{ + int partner_id_chk = 1; + char *partner_id = NULL; + char *ret_partner_id = NULL; + + ret_partner_id = get_id_pstore(partner_id_chk,partner_id); + if (ret_partner_id != NULL) + { + WebcfgDebug("PartnerID returned from lib is %s\n", ret_partner_id); + return ret_partner_id; + } + else + { + WebcfgError("Failed to GetValue for PartnerID\n"); + return NULL; + } +} + +char * getAccountID() +{ + int acc_id_chk = 0; + char *account_id = NULL; + char *ret_account_id = NULL; + + ret_account_id = get_id_pstore(acc_id_chk,account_id); + if (ret_account_id != NULL) + { + WebcfgDebug("AccountID returned from lib is %s\n", ret_account_id); + return ret_account_id; + } + else + { + WebcfgError("Failed to GetValue for AccountID\n"); + return NULL; + } +} + +char * getFirmwareUpgradeStartTime() +{ + char * start_time = NULL; + + start_time = malloc(BFR_SIZE_32*sizeof(char)); + if (!start_time) + { + WebcfgError("%s : start_time couldnt be assigned with memory\n",__func__); + return NULL; + } + + cpeabStrncpy(start_time,"7200",strlen("7200")+1); + return start_time; +} + +char * getFirmwareUpgradeEndTime() +{ + char * end_time = NULL; + + end_time = malloc(BFR_SIZE_32*sizeof(char)); + if (!end_time) + { + WebcfgError("%s : end_time couldnt be assigned with memory\n",__func__); + return NULL; + } + + cpeabStrncpy(end_time,"14400",strlen("14400")+1); + return end_time; +} + +int Get_Webconfig_URL( char *pString) +{ + char url[128]; + int ret = RETURN_ERR; + + memset(url,0,sizeof(url)); + + if (json_string_value_get(WEBCFG_URL_PARAM,url, sizeof(url))) + { + cpeabStrncpy(pString,url,sizeof(url)); + WebcfgDebug("Successfully fetched Webconfig URL : [%s]. \n", url); + ret = RETURN_OK; + } + else{ + WebcfgError("Error! Failed to fetch Webconfig URL\n"); + } + return ret; +} + +int Set_Webconfig_URL( char *pString) +{ + int ret = RETURN_ERR; + + if (json_string_value_set(WEBCFG_URL_PARAM, pString) == true) + { + WebcfgDebug("Successfully set Webconfig URL \n"); + ret = RETURN_OK; + } + else{ + WebcfgError("Error! Failed to set Webconfig URL\n"); + } + return ret; +} + +int Get_Supplementary_URL(char *pString) +{ + char url[128]; + int ret = RETURN_ERR; + + memset(url,0,sizeof(url)); + + if (json_string_value_get(WEBCFG_SUPPLEMENTARY_TELEMETRY_PARAM,url, sizeof(url))) + { + WebcfgDebug("Successfully fetched Webconfig Supp URL : [%s] \n", url); + cpeabStrncpy(pString,url,sizeof(url)); + ret = RETURN_OK; + } + else{ + WebcfgError("Error! Failed to fetch Webconfig Supp URL\n"); + } + return ret; +} + +int Set_Supplementary_URL(char *pString) +{ + int ret = RETURN_ERR; + + if (json_string_value_set(WEBCFG_SUPPLEMENTARY_TELEMETRY_PARAM, pString) == true) + { + WebcfgDebug("Successfully set Webconfig URL \n"); + ret = RETURN_OK; + } + else{ + WebcfgError("Error! Failed to set Webconfig Supp URL\n"); + } + return ret; +} + +/** + * To persist TR181 parameter values in PSM DB. + */ +int rbus_StoreValueIntoDB(char *paramName, char *value) +{ + int ret = RETURN_ERR; + + if (strncmp(paramName,WEBCFG_RFC_PARAM,WEBCFG_MAX_PARAM_LEN) == 0) + { + if (json_string_value_set(WEBCFG_RFC_PARAM,value) == RETURN_OK) + { + WebcfgDebug("%s : Successfully stored [%s] = [%s]. \n",__func__,WEBCFG_RFC_PARAM,value); + ret = RETURN_OK; + } + } + else if (strncmp(paramName,PARAM_RFC_ENABLE,WEBCFG_MAX_PARAM_LEN) == 0) + { + if (json_string_value_set(PARAM_RFC_ENABLE,value) == RETURN_OK) + { + WebcfgDebug("%s : Successfully stored [%s] = [%s]. \n",__func__,PARAM_RFC_ENABLE,value); + ret = RETURN_OK; + } + } + else if (strncmp(paramName,WEBCFG_URL_PARAM,WEBCFG_MAX_PARAM_LEN) == 0) + { + if (Set_Webconfig_URL(value) == RETURN_OK) + { + WebcfgDebug("%s : Successfully stored [%s] = [%s]. \n",__func__,WEBCFG_URL_PARAM,value); + ret = RETURN_OK; + } + } + else if (strncmp(paramName,WEBCFG_SUPPLEMENTARY_TELEMETRY_PARAM,WEBCFG_MAX_PARAM_LEN) == 0) + { + if (Set_Supplementary_URL(value) == RETURN_OK) + { + WebcfgDebug("%s : Successfully stored [%s] = [%s]. \n",__func__,WEBCFG_SUPPLEMENTARY_TELEMETRY_PARAM,value); + ret = RETURN_OK; + } + } + else { + WebcfgError("Invalid Param Name \n"); + } + return ret; +} +/** + * To fetch TR181 parameter values from PSM DB. + */ +int rbus_GetValueFromDB( char* paramName, char** paramValue) +{ + char value_str[256]; + int ret = RETURN_ERR; + + memset(value_str,0,sizeof(value_str)); + + if (strncmp(paramName,WEBCFG_RFC_PARAM,WEBCFG_MAX_PARAM_LEN) == 0) + { + if (json_string_value_get(WEBCFG_RFC_PARAM,value_str, sizeof(value_str))) + { + *paramValue = strdup(value_str); + WebcfgDebug("%s : Successfully fetched [%s] = [%s]. \n",__func__,WEBCFG_RFC_PARAM,*paramValue); + ret = RETURN_OK; + } + } + else if (strncmp(paramName,PARAM_RFC_ENABLE,WEBCFG_MAX_PARAM_LEN) == 0) + { + if (json_string_value_get(PARAM_RFC_ENABLE,value_str, sizeof(value_str))) + { + *paramValue = strdup(value_str); + WebcfgDebug("%s : Successfully fetched [%s] = [%s]. \n",__func__,PARAM_RFC_ENABLE,*paramValue); + ret = RETURN_OK; + } + } + else if (strncmp(paramName,WEBCFG_URL_PARAM,WEBCFG_MAX_PARAM_LEN) == 0) + { + if (Get_Webconfig_URL(value_str) == RETURN_OK) + { + *paramValue = strdup(value_str); + WebcfgDebug("%s : Successfully fetched [%s] = [%s]. \n",__func__,WEBCFG_URL_PARAM,*paramValue); + ret = RETURN_OK; + } + } + else if (strncmp(paramName,WEBCFG_SUPPLEMENTARY_TELEMETRY_PARAM,WEBCFG_MAX_PARAM_LEN) == 0) + { + if (Get_Supplementary_URL(value_str) == RETURN_OK) + { + *paramValue = strdup(value_str); + WebcfgDebug("%s : Successfully fetched [%s] = [%s]. \n",__func__,WEBCFG_SUPPLEMENTARY_TELEMETRY_PARAM,*paramValue); + ret = RETURN_OK; + } + } + else + { + WebcfgError("Invalid Param Name \n"); + } + return ret; +} + +int rbus_waitUntilSystemReady() +{ + return RETURN_OK; +} diff --git a/src/pods/include/cpeabs_ovsdb_utils.h b/src/pods/include/cpeabs_ovsdb_utils.h new file mode 100644 index 0000000..6b8e7ce --- /dev/null +++ b/src/pods/include/cpeabs_ovsdb_utils.h @@ -0,0 +1,13 @@ +/* SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#define OVSDB_COL_NUM 256 +#define OVSDB_COL_STR 1024 +#define UUID_STR_LEN 36 +#define OVSDB_SOCK_PATH "/var/run/db.sock" + +bool ovsdb_string_value_get(char *table,json_t *where, int coln, char * colv[],char *result_str, unsigned int len ); +bool ovsdb_parse_where(json_t *where, char *_str, bool is_parent_where); +void cpeabStrncpy(char *destStr, const char *srcStr, size_t destSize); diff --git a/src/pods/include/cpeabs_pod.h b/src/pods/include/cpeabs_pod.h new file mode 100644 index 0000000..ee562b0 --- /dev/null +++ b/src/pods/include/cpeabs_pod.h @@ -0,0 +1,33 @@ +/* SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef __CPEABS_POD_H__ +#define __CPEABS_POD_H__ + +#include +/*----------------------------------------------------------------------------*/ +/* Macros */ +/*----------------------------------------------------------------------------*/ +#define UNUSED(x) (void )(x) +#define MAX_BUFF_SIZE 256 + +/** + * @brief Enables or disables debug logs. + */ + +#define WebConfigLog(...) printf(__VA_ARGS__) + +#define WebcfgError(...) printf(__VA_ARGS__) +#define WebcfgInfo(...) printf(__VA_ARGS__) +#define WebcfgDebug(...) printf(__VA_ARGS__) + +/*----------------------------------------------------------------------------*/ +/* Data Structures */ +/*----------------------------------------------------------------------------*/ +/* none */ +/*----------------------------------------------------------------------------*/ +/* External Functions */ +/*----------------------------------------------------------------------------*/ +/* none */ +#endif + diff --git a/src/rdkb/impl.c b/src/rdkb/impl.c new file mode 100644 index 0000000..bcccf45 --- /dev/null +++ b/src/rdkb/impl.c @@ -0,0 +1,706 @@ +/* SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cpeabs.h" +#include "cpeabs_rdkb.h" +/*----------------------------------------------------------------------------*/ +/* Macros */ +/*----------------------------------------------------------------------------*/ +#define SERIAL_NUMBER "Device.DeviceInfo.SerialNumber" +#define FIRMWARE_VERSION "Device.DeviceInfo.X_CISCO_COM_FirmwareName" +#define DEVICE_BOOT_TIME "Device.DeviceInfo.X_RDKCENTRAL-COM_BootTime" +#define MODEL_NAME "Device.DeviceInfo.ModelName" +#define PRODUCT_CLASS "Device.DeviceInfo.ProductClass" +#define CONN_CLIENT_PARAM "Device.X_RDK_Webpa.ConnectedClientNotify" +#define LAST_REBOOT_REASON "Device.DeviceInfo.X_RDKCENTRAL-COM_LastRebootReason" +#define PARTNER_ID "Device.DeviceInfo.X_RDKCENTRAL-COM_Syndication.PartnerId" +#define ACCOUNT_ID "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AccountInfo.AccountID" +#define FIRMW_START_TIME "Device.DeviceInfo.X_RDKCENTRAL-COM_MaintenanceWindow.FirmwareUpgradeStartTime" +#define FIRMW_END_TIME "Device.DeviceInfo.X_RDKCENTRAL-COM_MaintenanceWindow.FirmwareUpgradeEndTime" + +#if defined(_COSA_BCM_MIPS_) +#define DEVICE_MAC "Device.DPoE.Mac_address" +#elif defined(PLATFORM_RASPBERRYPI) +#define DEVICE_MAC "Device.Ethernet.Interface.5.MACAddress" +#elif defined(RDKB_EMU) +#define DEVICE_MAC "Device.DeviceInfo.X_COMCAST-COM_WAN_MAC" +#elif defined(_HUB4_PRODUCT_REQ_) +#define DEVICE_MAC "Device.DeviceInfo.X_COMCAST-COM_WAN_MAC" +#else +#define DEVICE_MAC "Device.X_CISCO_COM_CableModem.MACAddress" +#endif + +#define WEBCFG_URL_PARAM "Device.X_RDK_WebConfig.URL" +#define WEBCFG_PARAM_SUPPLEMENTARY_SERVICE "Device.X_RDK_WebConfig.SupplementaryServiceUrls." +#define SYSTEM_READY_PARM "Device.CR.SystemReady" + +#define UNUSED(x) (void )(x) +#define MAX_BUFF_SIZE 256 +/*----------------------------------------------------------------------------*/ +/* Data Structures */ +/*----------------------------------------------------------------------------*/ +typedef struct +{ + char *paramName; + char *paramValue; + rbusValueType_t type; +} rbusParamVal_t; +/*----------------------------------------------------------------------------*/ +/* File Scoped Variables */ +/*----------------------------------------------------------------------------*/ +static bool isRbus = false ; +char deviceMAC[32]={'\0'}; +/*----------------------------------------------------------------------------*/ +/* Function Prototypes */ +/*----------------------------------------------------------------------------*/ +void __attribute__((weak)) getValues_rbus(const char *paramName[], const unsigned int paramCount, int index, money_trace_spans *timeSpan, param_t ***paramArr, int *retValCount, WDMP_STATUS *retStatus); +static bool isRbusEnabled(); +void macIDToLower(char macValue[],char macConverted[]); +void cpeabStrncpy(char *destStr, const char *srcStr, size_t destSize); +rbusHandle_t __attribute__((weak)) get_global_rbus_handle(void); +static void systemReadyEventHandler(rbusHandle_t handle, rbusEvent_t const* event, rbusEventSubscription_t* subscription); +static void subscribeSystemReadyEvent(); +static int rbus_checkIfSystemReady(); +static int webcfgRbusRegisterWithCR(); +/*----------------------------------------------------------------------------*/ +/* External Functions */ +/*----------------------------------------------------------------------------*/ + +void cpeabStrncpy(char *destStr, const char *srcStr, size_t destSize) +{ + strncpy(destStr, srcStr, destSize-1); + destStr[destSize-1] = '\0'; +} + +void macIDToLower(char macValue[],char macConverted[]) +{ + int i = 0; + int j; + char *token[32]; + char tmp[32]; + cpeabStrncpy(tmp, macValue, sizeof(tmp)); + token[i] = strtok(tmp, ":"); + if(token[i]!=NULL) + { + cpeabStrncpy(macConverted, token[i], 32); + i++; + } + while ((token[i] = strtok(NULL, ":")) != NULL) + { + strncat(macConverted, token[i], 31); + macConverted[31]='\0'; + i++; + } + macConverted[31]='\0'; + for(j = 0; macConverted[j]; j++) + { + macConverted[j] = tolower(macConverted[j]); + } +} + +char* get_deviceMAC() +{ + if(strlen(deviceMAC) != 0) + { + WebcfgDebug("deviceMAC returned %s\n", deviceMAC); + return deviceMAC; + } + + char *macID = NULL; + char deviceMACValue[32] = { '\0' }; + macID = getParamValue(DEVICE_MAC); + if (macID != NULL) + { + cpeabStrncpy(deviceMACValue, macID, strlen(macID)+1); + macIDToLower(deviceMACValue, deviceMAC); + WebcfgDebug("deviceMAC: %s\n",deviceMAC); + cpeabs_free(macID); + } + WebcfgDebug("deviceMAC returned from lib is %s\n", deviceMAC); + return deviceMAC; +} + +char * getSerialNumber() +{ + char *serialNum = NULL; + serialNum = getParamValue(SERIAL_NUMBER); + WebcfgDebug("serialNum returned from lib is %s\n", serialNum); + return serialNum; +} + +char * getDeviceBootTime() +{ + char *bootTime = NULL; + bootTime = getParamValue(DEVICE_BOOT_TIME); + WebcfgDebug("bootTime returned from lib is %s\n", bootTime); + return bootTime; +} + +char * getProductClass() +{ + char *productClass = NULL; + productClass = getParamValue(PRODUCT_CLASS); + WebcfgDebug("productClass returned from lib is %s\n", productClass); + return productClass; +} + +char * getModelName() +{ + char *modelName = NULL; + modelName = getParamValue(MODEL_NAME); + WebcfgDebug("modelName returned from lib is %s\n", modelName); + return modelName; +} + +char * getFirmwareVersion() +{ + char *firmware = NULL; + firmware = getParamValue(FIRMWARE_VERSION); + WebcfgDebug("firmware returned from lib is %s\n", firmware); + return firmware; +} + +char * getConnClientParamName() +{ + return CONN_CLIENT_PARAM; +} + +char * getRebootReason() +{ + char *reboot_reason = NULL; + reboot_reason = getParamValue(LAST_REBOOT_REASON); + WebcfgDebug("reboot_reason returned from lib is %s\n", reboot_reason); + return reboot_reason; +} + +char * getPartnerID() +{ + char *partnerId = NULL; + partnerId = getParamValue(PARTNER_ID); + WebcfgDebug("partnerId returned from lib is %s\n", partnerId); + return partnerId; +} + +char * getAccountID() +{ + char *accountId = NULL; + accountId = getParamValue(ACCOUNT_ID); + WebcfgDebug("accountId returned from lib is %s\n", accountId); + return accountId; +} + +char * getFirmwareUpgradeStartTime() +{ + char *FirmwareUpgradeStartTime = NULL; + FirmwareUpgradeStartTime = getParamValue(FIRMW_START_TIME); + WebcfgDebug("FirmwareUpgradeStartTime returned from lib is %s\n", FirmwareUpgradeStartTime); + return FirmwareUpgradeStartTime; +} + +char * getFirmwareUpgradeEndTime() +{ + char *FirmwareUpgradeEndTime = NULL; + FirmwareUpgradeEndTime = getParamValue(FIRMW_END_TIME); + WebcfgDebug("FirmwareUpgradeEndTime returned from lib is %s\n", FirmwareUpgradeEndTime); + return FirmwareUpgradeEndTime; +} + +bool isRbusEnabled() +{ + if(RBUS_ENABLED == rbus_checkStatus()) + { + isRbus = true; + } + else + { + isRbus = false; + } + WebcfgDebug("Webconfig util RBUS mode active status = %s\n", isRbus ? "true":"false"); + return isRbus; +} + +int Get_Webconfig_URL( char *pString) +{ + char *tempUrl = NULL; + int retPsmGet = 0; + if(isRbusEnabled()) + { + retPsmGet = rbus_GetValueFromDB( WEBCFG_URL_PARAM, &tempUrl); + WebcfgDebug("Get_Webconfig_URL. retPsmGet %d tempUrl %s\n", retPsmGet, tempUrl); + if (retPsmGet == RBUS_ERROR_SUCCESS) + { + if(tempUrl !=NULL) + { + cpeabStrncpy(pString, tempUrl, strlen(tempUrl)+1); + } + WebcfgDebug("Get_Webconfig_URL. pString %s\n", pString); + } + else + { + WebcfgError("psm_get failed ret %d for parameter %s\n", retPsmGet, WEBCFG_URL_PARAM); + } + } + WebcfgDebug("Get_Webconfig_URL strong fn from lib\n"); + return retPsmGet; +} + +int Set_Webconfig_URL( char *pString) +{ + int retPsmSet = 0; + if(isRbusEnabled()) + { + retPsmSet = rbus_StoreValueIntoDB( WEBCFG_URL_PARAM, pString ); + WebcfgDebug("Set_Webconfig_URL. retPsmSet %d pString %s\n", retPsmSet, pString); + + if (retPsmSet != RBUS_ERROR_SUCCESS) + { + WebcfgError("psm_set failed ret %d for parameter %s and value %s\n", retPsmSet, WEBCFG_URL_PARAM, pString); + return 0; + } + else + { + WebcfgDebug("psm_set success ret %d for parameter %s and value %s\n", retPsmSet, WEBCFG_URL_PARAM, pString); + } + } + return retPsmSet; +} + +int Get_Supplementary_URL( char *name, char *pString) +{ + char *tempUrl = NULL; + int retPsmGet = 0; + if(isRbusEnabled()) + { + char *tempParam = (char *) malloc (sizeof(char)*MAX_BUFF_SIZE); + if(tempParam !=NULL) + { + snprintf(tempParam, MAX_BUFF_SIZE, "%s%s", WEBCFG_PARAM_SUPPLEMENTARY_SERVICE, name); + WebcfgDebug("tempParam is %s\n", tempParam); + retPsmGet = rbus_GetValueFromDB( tempParam, &tempUrl); + if (retPsmGet == RBUS_ERROR_SUCCESS) + { + WebcfgDebug("Get_Supplementary_URL. retPsmGet %d tempUrl %s\n", retPsmGet, tempUrl); + if(tempUrl !=NULL) + { + cpeabStrncpy(pString, tempUrl, strlen(tempUrl)+1); + } + WebcfgDebug("Get_Supplementary_URL. pString %s\n", pString); + cpeabs_free(tempParam); + } + else + { + WebcfgError("psm_get failed ret %d for parameter %s\n", retPsmGet, tempParam); + cpeabs_free(tempParam); + } + } + } + return retPsmGet; +} + +int Set_Supplementary_URL( char *name, char *pString) +{ + int retPsmSet = 0; + if(isRbusEnabled()) + { + char *tempParam = (char *) malloc (sizeof(char)*MAX_BUFF_SIZE); + if(tempParam !=NULL) + { + if ((name != NULL) && (strncmp(name, "Telemetry",strlen(name)+1)) == 0) + { + snprintf(tempParam, MAX_BUFF_SIZE, "%s%s", WEBCFG_PARAM_SUPPLEMENTARY_SERVICE, name); + WebcfgDebug("tempParam is %s\n", tempParam); + retPsmSet = rbus_StoreValueIntoDB( tempParam, pString ); + if (retPsmSet != RBUS_ERROR_SUCCESS) + { + WebcfgError("psm_set failed ret %d for parameter %s%s and value %s\n", retPsmSet, WEBCFG_PARAM_SUPPLEMENTARY_SERVICE, name, pString); + cpeabs_free(tempParam); + return 0; + } + else + { + WebcfgDebug("psm_set success ret %d for parameter %s%s and value %s\n",retPsmSet, WEBCFG_PARAM_SUPPLEMENTARY_SERVICE, name, pString); + } + } + else + { + WebcfgError("Invalid supplementary doc name\n"); + } + cpeabs_free(tempParam); + } + } + return retPsmSet; +} + +char * getParamValue(char *paramName) +{ + if(isRbusEnabled()) + { + int paramCount=0; + WDMP_STATUS ret = WDMP_FAILURE; + int count=0; + const char *getParamList[1]; + getParamList[0] = paramName; + + char *paramValue = (char *) malloc(sizeof(char)*64); + paramCount = sizeof(getParamList)/sizeof(getParamList[0]); + param_t **parametervalArr = (param_t **) malloc(sizeof(param_t *) * paramCount); + + WebcfgDebug("paramName : %s paramCount %d\n",getParamList[0], paramCount); + getValues_rbus(getParamList, paramCount, 0, NULL, ¶metervalArr, &count, &ret); + + if (ret == WDMP_SUCCESS ) + { + cpeabStrncpy(paramValue, parametervalArr[0]->value,64); + cpeabs_free(parametervalArr[0]->name); + cpeabs_free(parametervalArr[0]->value); + cpeabs_free(parametervalArr[0]); + } + else + { + WebcfgError("Failed to GetValue for %s\n", getParamList[0]); + cpeabs_free(paramValue); + } + cpeabs_free(parametervalArr); + WebcfgDebug("getParamValue : paramValue is %s\n", paramValue); + return paramValue; + } + WebcfgError("getParamValue : returns NULL\n"); + return NULL; +} + +/** + * To persist TR181 parameter values in PSM DB. + */ +int rbus_StoreValueIntoDB(char *paramName, char *value) +{ + rbusHandle_t rbus_handle; + rbusObject_t inParams; + rbusObject_t outParams; + rbusValue_t setvalue; + int rc = RBUS_ERROR_SUCCESS; + + rbus_handle = get_global_rbus_handle(); + if(!rbus_handle) + { + WebcfgError("rbus_StoreValueIntoDB failed as rbus_handle is empty\n"); + return 1; + } + + rbusObject_Init(&inParams, NULL); + rbusValue_Init(&setvalue); + rbusValue_SetString(setvalue, value); + rbusObject_SetValue(inParams, paramName, setvalue); + rbusValue_Release(setvalue); + + rc = rbusMethod_Invoke(rbus_handle, "SetPSMRecordValue()", inParams, &outParams); + rbusObject_Release(inParams); + if(rc != RBUS_ERROR_SUCCESS) + { + WebcfgError("SetPSMRecordValue failed with err %d: %s\n", rc, rbusError_ToString(rc)); + } + else + { + WebcfgDebug("SetPSMRecordValue is success\n"); + rbusObject_Release(outParams); + return 0; + } + return 1; +} + +/** + * To fetch TR181 parameter values from PSM DB. + */ +int rbus_GetValueFromDB( char* paramName, char** paramValue) +{ + rbusHandle_t rbus_handle; + rbusObject_t inParams; + rbusObject_t outParams; + rbusValue_t setvalue; + int rc = RBUS_ERROR_SUCCESS; + + rbus_handle = get_global_rbus_handle(); + if(!rbus_handle) + { + WebcfgError("rbus_GetValueFromDB failed as rbus_handle is empty\n"); + return 1; + } + + rbusObject_Init(&inParams, NULL); + rbusValue_Init(&setvalue); + rbusValue_SetString(setvalue, "value"); + rbusObject_SetValue(inParams, paramName, setvalue); + rbusValue_Release(setvalue); + + rc = rbusMethod_Invoke(rbus_handle, "GetPSMRecordValue()", inParams, &outParams); + rbusObject_Release(inParams); + if(rc != RBUS_ERROR_SUCCESS) + { + WebcfgError("GetPSMRecordValue failed with err %d: %s\n", rc, rbusError_ToString(rc)); + } + else + { + WebcfgDebug("GetPSMRecordValue is success\n"); + rbusProperty_t prop = NULL; + rbusValue_t value = NULL; + char *str_value = NULL; + prop = rbusObject_GetProperties(outParams); + while(prop) + { + value = rbusProperty_GetValue(prop); + if(value) + { + str_value = rbusValue_ToString(value,NULL,0); + if(str_value) + { + WebcfgDebug("Parameter Name : %s\n", rbusProperty_GetName(prop)); + WebcfgDebug("Parameter Value fetched: %s\n", str_value); + } + } + prop = rbusProperty_GetNext(prop); + } + if(str_value !=NULL) + { + *paramValue = strdup(str_value); + cpeabs_free(str_value); + WebcfgDebug("Requested param DB value [%s]\n", *paramValue); + } + rbusObject_Release(outParams); + return 0; + } + return 1; +} + +void getValues_rbus(const char *paramName[], const unsigned int paramCount, int index, money_trace_spans *timeSpan, param_t ***paramArr, int *retValCount, WDMP_STATUS *retStatus) +{ + UNUSED(paramName); + UNUSED(paramCount); + UNUSED(index); + UNUSED(timeSpan); + UNUSED(paramArr); + UNUSED(retValCount); + UNUSED(retStatus); + return; +} + +rbusHandle_t get_global_rbus_handle(void) +{ + return 0; +} + +int rbus_waitUntilSystemReady() +{ + int ret = 0; + int fd; + + if(rbus_checkIfSystemReady()) + { + WebcfgInfo("Checked CR - System is ready, proceed with webconfig startup\n"); + if((fd = creat("/var/tmp/webcfgcacheready", S_IRUSR | S_IWUSR)) == -1) + { + WebcfgError("/var/tmp/webcfgcacheready file creation failed with error:%d\n", errno); + } + else + { + close(fd); + } + } + else + { + webcfgRbusRegisterWithCR(); + subscribeSystemReadyEvent(); + + FILE *file; + int wait_time = 0; + int total_wait_time = 0; + + //Wait till Call back touches the indicator to proceed further + while((file = fopen("/var/tmp/webcfgcacheready", "r")) == NULL) + { + WebcfgInfo("Waiting for system ready signal\n"); + //After waiting for 24 * 5 = 120s (2mins) send message to CR to query for system ready + if(wait_time == 24) + { + wait_time = 0; + if(rbus_checkIfSystemReady()) + { + WebcfgInfo("Checked CR - System is ready\n"); + if((fd = creat("/var/tmp/webcfgcacheready", S_IRUSR | S_IWUSR)) == -1) + { + WebcfgError("/var/tmp/webcfgcacheready file creation failed, error:%d\n", errno); + } + else + { + close(fd); + } + break; + } + else + { + WebcfgInfo("Queried CR for system ready after waiting for 2 mins, it is still not ready\n"); + if(total_wait_time >= 84) + { + WebcfgInfo("Queried CR for system ready after waiting for 7 mins, it is still not ready. Proceeding ...\n"); + ret = 1; + break; + } + } + } + sleep(5); + wait_time++; + total_wait_time++; + }; + // In case of WebConfig restart, we should be having cacheready already touched. + if(file != NULL) + { + WebcfgInfo("/var/tmp/webcfgcacheready file exists, proceed with webconfig start up\n"); + fclose(file); + } + } + return ret; +} + +static void subscribeSystemReadyEvent() +{ + int rc = RBUS_ERROR_SUCCESS; + rbusHandle_t rbus_handle; + + rbus_handle = get_global_rbus_handle(); + if(!rbus_handle) + { + WebcfgError("subscribeSystemReadyEvent failed as rbus_handle is empty\n"); + return; + } + + rc = rbusEvent_Subscribe(rbus_handle,SYSTEM_READY_PARM,systemReadyEventHandler,"webconfig",0); + if(rc != RBUS_ERROR_SUCCESS) + WebcfgError("systemready rbusEvent_Subscribe failed: %d, %s\n", rc, rbusError_ToString(rc)); + else + WebcfgInfo("systemready rbusEvent_Subscribe was successful\n"); +} + +static void systemReadyEventHandler(rbusHandle_t handle, rbusEvent_t const* event, rbusEventSubscription_t* subscription) +{ + (void)handle; + (void)subscription; + int eventValue = 0; + rbusValue_t value = NULL; + int fd; + + value = rbusObject_GetValue(event->data, "value"); + eventValue = (int) rbusValue_GetBoolean(value); + WebcfgDebug("eventValue is %d\n", eventValue); + if(eventValue) + { + if((fd = creat("/var/tmp/webcfgcacheready", S_IRUSR | S_IWUSR)) == -1) + { + WebcfgError("Failed to create /var/tmp/webcfgcacheready file, error:%d\n", errno); + } + else + { + close(fd); + } + WebcfgInfo("Received system ready signal, created /var/tmp/webcfgcacheready file\n"); + } +} + +/** + * rbus_checkIfSystemReady Function to query CR and check if system is ready. + * This is just in case webconfig registers for the systemReadySignal event late. + * If SystemReadySignal is already sent then this will return 1 indicating system is ready. + */ +static int rbus_checkIfSystemReady() +{ + int rc = -1; + rbusHandle_t rbus_handle; + int sysVal = 0; + + rbus_handle = get_global_rbus_handle(); + if(!rbus_handle) + { + WebcfgError("rbus_checkIfSystemReady failed as rbus_handle is empty\n"); + return rc; + } + + rbusValue_t value; + rc = rbus_get(rbus_handle, SYSTEM_READY_PARM, &value); + if(rc != RBUS_ERROR_SUCCESS) + { + WebcfgError("rbus_checkIfSystemReady failed with err %d: %s\n", rc, rbusError_ToString(rc)); + return rc; + } + else + { + WebcfgDebug("rbus_checkIfSystemReady returns %d\n", rbusValue_GetBoolean(value)); + sysVal = (int) rbusValue_GetBoolean(value); + WebcfgDebug("sysVal is %d\n", sysVal); + } + rbusValue_Release(value); + if(sysVal) + { + WebcfgDebug("SystemReady returns 1\n"); + return 1; + } + else + { + WebcfgDebug("SystemReady returns 0\n"); + } + return rc; +} + +/** + * To register webconfig component with component Registery CR. + */ +static int webcfgRbusRegisterWithCR() +{ + rbusHandle_t rbus_handle; + rbusObject_t inParams; + rbusObject_t outParams; + rbusValue_t value; + int rc = RBUS_ERROR_SUCCESS; + + rbus_handle = get_global_rbus_handle(); + if(!rbus_handle) + { + WebcfgError("webcfgRbusRegisterWithCR failed as rbus_handle is empty\n"); + return 1; + } + + rbusObject_Init(&inParams, NULL); + + rbusValue_Init(&value); + rbusValue_SetString(value, "webconfig"); + rbusObject_SetValue(inParams, "name", value); + rbusValue_Release(value); + + rbusValue_Init(&value); + rbusValue_SetInt32(value, 1); + rbusObject_SetValue(inParams, "version", value); + rbusValue_Release(value); + + rc = rbusMethod_Invoke(rbus_handle, "Device.CR.RegisterComponent()", inParams, &outParams); + rbusObject_Release(inParams); + if(rc != RBUS_ERROR_SUCCESS) + { + WebcfgError("Device.CR.RegisterComponent failed with err %d: %s\n", rc, rbusError_ToString(rc)); + } + else + { + WebcfgInfo("Device.CR.RegisterComponent is success\n"); + rbusObject_Release(outParams); + return 0; + } + return 1; +} diff --git a/src/rdkb/include/cpeabs_rdkb.h b/src/rdkb/include/cpeabs_rdkb.h new file mode 100644 index 0000000..2a8eab1 --- /dev/null +++ b/src/rdkb/include/cpeabs_rdkb.h @@ -0,0 +1,48 @@ +/* SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef __CPEABS_RDKB_H__ +#define __CPEABS_RDKB_H__ + +#include +#include +#include + +/*----------------------------------------------------------------------------*/ +/* Macros */ +/*----------------------------------------------------------------------------*/ +#define UNUSED(x) (void )(x) +#define MAX_BUFF_SIZE 256 + +/** + * @brief Enables or disables debug logs. + */ +#if defined BUILD_YOCTO + +#define WEBCFG_LOG_MODULE "WEBCONFIG" +#define WEBCFG_RDK_LOG_MODULE "LOG.RDK.WEBCONFIG" + +#define WebConfigLog(...) __cimplog_rdk_generic(WEBCFG_RDK_LOG_MODULE, WEBCFG_LOG_MODULE, LEVEL_INFO, __VA_ARGS__) + +#define WebcfgError(...) __cimplog_rdk_generic(WEBCFG_RDK_LOG_MODULE, WEBCFG_LOG_MODULE, LEVEL_ERROR, __VA_ARGS__) +#define WebcfgInfo(...) __cimplog_rdk_generic(WEBCFG_RDK_LOG_MODULE, WEBCFG_LOG_MODULE, LEVEL_INFO, __VA_ARGS__) +#define WebcfgDebug(...) __cimplog_rdk_generic(WEBCFG_RDK_LOG_MODULE, WEBCFG_LOG_MODULE, LEVEL_DEBUG, __VA_ARGS__) +#else +#define WebConfigLog(...) printf(__VA_ARGS__) + +#define WebcfgError(...) printf(__VA_ARGS__) +#define WebcfgInfo(...) printf(__VA_ARGS__) +#define WebcfgDebug(...) printf(__VA_ARGS__) + +#endif + +/*----------------------------------------------------------------------------*/ +/* Data Structures */ +/*----------------------------------------------------------------------------*/ +/* none */ +/*----------------------------------------------------------------------------*/ +/* External Functions */ +/*----------------------------------------------------------------------------*/ +/* none */ +#endif + diff --git a/subprojects/cimplog.wrap b/subprojects/cimplog.wrap new file mode 100644 index 0000000..456bd9c --- /dev/null +++ b/subprojects/cimplog.wrap @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +[wrap-git] +directory = cimplog + +url = https://github.com/Comcast/cimplog.git +revision = 8a5fb3c2f182241d17f5342bea5b7688c28cd1fd +patch_filename = cimplog.tar.gz + +[provide] +libcimplog = libcimplog_dep diff --git a/subprojects/cjson.wrap b/subprojects/cjson.wrap new file mode 100644 index 0000000..f65f72f --- /dev/null +++ b/subprojects/cjson.wrap @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +[wrap-file] +directory = cJSON-1.7.14 +source_url = https://github.com/DaveGamble/cJSON/archive/refs/tags/v1.7.14.tar.gz +source_filename = v1.7.14.tar.gz +source_hash = fb50a663eefdc76bafa80c82bc045af13b1363e8f45cec8b442007aef6a41343 +patch_filename = cjson_1.7.14-1_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/cjson_1.7.14-1/get_patch +patch_hash = 82d7a029637bdd6696a89075907581768e7088c20b1c69f400cb6e15e716d803 + +[provide] +libcjson = libcjson_dep diff --git a/subprojects/jansson.wrap b/subprojects/jansson.wrap new file mode 100644 index 0000000..c6dcf30 --- /dev/null +++ b/subprojects/jansson.wrap @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +[wrap-git] +directory = jansson + +url = https://github.com/akheron/jansson.git +revision = addeeef408cf9e4711a234e04fc2c4bd7357561b +patch_filename = jansson.tar.gz + +[provide] +libjansson = libjansson_dep diff --git a/subprojects/rtMessage.wrap b/subprojects/rtMessage.wrap new file mode 100644 index 0000000..0d5bd3d --- /dev/null +++ b/subprojects/rtMessage.wrap @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +[wrap-git] +directory = rtMessage + +url = https://github.com/guruchandru/rdk-rtmessage.git +revision = rdk-next +patch_filename = rtMessage.tar.gz + +[provide] +librtMessage = librtMessage_dep diff --git a/subprojects/wdmp.wrap b/subprojects/wdmp.wrap new file mode 100644 index 0000000..db970b8 --- /dev/null +++ b/subprojects/wdmp.wrap @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +[wrap-git] +directory = wdmp + +url = https://github.com/Comcast/wdmp-c.git +revision = 796dddbcfa7686ec63536d950775e79b52ee5c3f +patch_filename = wdmp.tar.gz + +[provide] +libwdmp = libwdmp_dep diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..187929e --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,84 @@ +# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -W -g -fprofile-arcs -ftest-coverage -O0") +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DTEST ") +set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -W -g -fprofile-arcs -ftest-coverage -O0") +set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage -O0") + +if(NOT DISABLE_VALGRIND) +set (MEMORY_CHECK valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v) +endif () + +link_directories ( ${LIBRARY_DIR} ) + +if (BUILD_YOCTO) +add_definitions(-DBUILD_YOCTO) +endif (BUILD_YOCTO) + +if (PLATFORM STREQUAL "DEVICE_GATEWAY") +add_definitions(-DDEVICE_GATEWAY) +elseif (PLATFORM STREQUAL "DEVICE_EXTENDER") +add_definitions(-DDEVICE_EXTENDER) +endif () + +if (PLATFORM STREQUAL "DEVICE_GATEWAY") + +#------------------------------------------------------------------------------- +# test_rdkb +#------------------------------------------------------------------------------- +add_test(NAME test_rdkb COMMAND ${MEMORY_CHECK} ./test_rdkb) + +set(SOURCES test_rdkb.c ${PROJECT_SOURCE_DIR}/src/rdkb/impl.c ${PROJECT_SOURCE_DIR}/src/common.c) + +add_executable(test_rdkb ${SOURCES}) + +target_link_libraries (test_rdkb -lcjson -lcunit -lmsgpackc -lwdmp-c -lcimplog -lpthread -lrbus ) + +target_link_libraries (test_rdkb gcov -Wl,--no-as-needed ) + + +elseif (PLATFORM STREQUAL "DEVICE_EXTENDER") + +#------------------------------------------------------------------------------- +# test_pods +#------------------------------------------------------------------------------- +add_test(NAME test_pods COMMAND ${MEMORY_CHECK} ./test_pods) + +set(SOURCES test_pods.c ${PROJECT_SOURCE_DIR}/src/pods/impl.c ${PROJECT_SOURCE_DIR}/src/pods/cpeabs_ovsdb_utils.c ${PROJECT_SOURCE_DIR}/src/common.c) + +add_executable(test_pods ${SOURCES}) + +target_link_libraries (test_pods -lcunit -ljansson) + +target_link_libraries (test_pods gcov -Wl,--no-as-needed ) + +else() + +#------------------------------------------------------------------------------- +# test_pc +#------------------------------------------------------------------------------- +add_test(NAME test_pc COMMAND ${MEMORY_CHECK} ./test_pc) + +set(SOURCES test_pc.c ${PROJECT_SOURCE_DIR}/src/pc/impl.c ) + +add_executable(test_pc ${SOURCES}) + +target_link_libraries (test_pc -lcunit) + +target_link_libraries (test_pc gcov -Wl,--no-as-needed ) + +endif() + +# Code coverage + +add_custom_target(coverage +COMMAND lcov -q --capture --directory +${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/test_common.dir/__/src --output-file test_common.info + +COMMAND lcov +-a test_common.info +--output-file coverage.info + +COMMAND genhtml coverage.info +WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/tests/test_pc.c b/tests/test_pc.c new file mode 100644 index 0000000..21ac1e7 --- /dev/null +++ b/tests/test_pc.c @@ -0,0 +1,74 @@ +/* SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include +#include "cpeabs.h" + +/*----------------------------------------------------------------------------*/ +/* Macros */ +/*----------------------------------------------------------------------------*/ +/* none */ + +/*----------------------------------------------------------------------------*/ +/* Data Structures */ +/*----------------------------------------------------------------------------*/ +/* none */ + +/*----------------------------------------------------------------------------*/ +/* File Scoped Variables */ +/*----------------------------------------------------------------------------*/ +/* none */ + +/*----------------------------------------------------------------------------*/ +/* Function Prototypes */ +/*----------------------------------------------------------------------------*/ +/* none */ + +/*----------------------------------------------------------------------------*/ +/* Tests */ +/*----------------------------------------------------------------------------*/ +void test_do_something() +{ + char * testget = getParamValue("test"); + printf("testget is %s\n", testget); +} + + +/*----------------------------------------------------------------------------*/ +/* Testing Framework */ +/*----------------------------------------------------------------------------*/ + +void add_suites(CU_pSuite *suite) +{ + *suite = CU_add_suite("common encoding tests", NULL, NULL); + CU_add_test(*suite, "Test do_something in test_pc", test_do_something); +} + +int main(void) +{ + unsigned rv = 1; + CU_pSuite suite = NULL; + + if (CUE_SUCCESS == CU_initialize_registry()) { + add_suites(&suite); + + if (NULL != suite) { + CU_basic_set_mode(CU_BRM_VERBOSE); + CU_basic_run_tests(); + printf("\n"); + CU_basic_show_failures(CU_get_failure_list()); + printf("\n\n"); + rv = CU_get_number_of_tests_failed(); + } + + CU_cleanup_registry(); + } + + if (0 != rv) { + return 1; + } + return 0; +} diff --git a/tests/test_pods.c b/tests/test_pods.c new file mode 100644 index 0000000..e80311f --- /dev/null +++ b/tests/test_pods.c @@ -0,0 +1,73 @@ +/* SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include +#include "cpeabs.h" +#include "cpeabs_ovsdb_utils.h" +/*----------------------------------------------------------------------------*/ +/* Macros */ +/*----------------------------------------------------------------------------*/ +/* none */ + +/*----------------------------------------------------------------------------*/ +/* Data Structures */ +/*----------------------------------------------------------------------------*/ +/* none */ + +/*----------------------------------------------------------------------------*/ +/* File Scoped Variables */ +/*----------------------------------------------------------------------------*/ +/* none */ + +/*----------------------------------------------------------------------------*/ +/* Function Prototypes */ +/*----------------------------------------------------------------------------*/ +/* none */ + +/*----------------------------------------------------------------------------*/ +/* Tests */ +/*----------------------------------------------------------------------------*/ +void test_do_something() +{ + printf("SUCCESS\n"); +} + + +/*----------------------------------------------------------------------------*/ +/* Testing Framework */ +/*----------------------------------------------------------------------------*/ + +void add_suites(CU_pSuite *suite) +{ + *suite = CU_add_suite("common encoding tests", NULL, NULL); + CU_add_test(*suite, "Test do_something", test_do_something); +} + +int main(void) +{ + unsigned rv = 1; + CU_pSuite suite = NULL; + + if (CUE_SUCCESS == CU_initialize_registry()) { + add_suites(&suite); + + if (NULL != suite) { + CU_basic_set_mode(CU_BRM_VERBOSE); + CU_basic_run_tests(); + printf("\n"); + CU_basic_show_failures(CU_get_failure_list()); + printf("\n\n"); + rv = CU_get_number_of_tests_failed(); + } + + CU_cleanup_registry(); + } + + if (0 != rv) { + return 1; + } + return 0; +} diff --git a/tests/test_rdkb.c b/tests/test_rdkb.c new file mode 100644 index 0000000..c9ab790 --- /dev/null +++ b/tests/test_rdkb.c @@ -0,0 +1,74 @@ +/* SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include +#include "cpeabs.h" + +/*----------------------------------------------------------------------------*/ +/* Macros */ +/*----------------------------------------------------------------------------*/ +/* none */ + +/*----------------------------------------------------------------------------*/ +/* Data Structures */ +/*----------------------------------------------------------------------------*/ +/* none */ + +/*----------------------------------------------------------------------------*/ +/* File Scoped Variables */ +/*----------------------------------------------------------------------------*/ +/* none */ + +/*----------------------------------------------------------------------------*/ +/* Function Prototypes */ +/*----------------------------------------------------------------------------*/ +/* none */ + +/*----------------------------------------------------------------------------*/ +/* Tests */ +/*----------------------------------------------------------------------------*/ +void test_do_something() +{ + char * name = getParamValue("test"); + printf("Name is %s\n", name); +} + + +/*----------------------------------------------------------------------------*/ +/* Testing Framework */ +/*----------------------------------------------------------------------------*/ + +void add_suites(CU_pSuite *suite) +{ + *suite = CU_add_suite("common encoding tests", NULL, NULL); + CU_add_test(*suite, "Test do_something", test_do_something); +} + +int main(void) +{ + unsigned rv = 1; + CU_pSuite suite = NULL; + + if (CUE_SUCCESS == CU_initialize_registry()) { + add_suites(&suite); + + if (NULL != suite) { + CU_basic_set_mode(CU_BRM_VERBOSE); + CU_basic_run_tests(); + printf("\n"); + CU_basic_show_failures(CU_get_failure_list()); + printf("\n\n"); + rv = CU_get_number_of_tests_failed(); + } + + CU_cleanup_registry(); + } + + if (0 != rv) { + return 1; + } + return 0; +} diff --git a/workaround.sh b/workaround.sh new file mode 100755 index 0000000..781e043 --- /dev/null +++ b/workaround.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +mkdir -p subprojects/packagefiles + +pushd wrapdb + +tar -czf rtMessage.tar.gz rtMessage +mv -f rtMessage.tar.gz ../subprojects/packagefiles/. + +tar -czf rbuscore.tar.gz rbuscore +mv -f rbuscore.tar.gz ../subprojects/packagefiles/. + +tar -czf rbus.tar.gz rbus +mv -f rbus.tar.gz ../subprojects/packagefiles/. + +tar -czf cimplog.tar.gz cimplog +mv -f cimplog.tar.gz ../subprojects/packagefiles/. + +tar -czf wdmp.tar.gz wdmp +mv -f wdmp.tar.gz ../subprojects/packagefiles/. + +tar -czf jansson.tar.gz jansson +mv -f jansson.tar.gz ../subprojects/packagefiles/. + +popd diff --git a/wrapdb/cimplog/meson.build b/wrapdb/cimplog/meson.build new file mode 100644 index 0000000..d206bab --- /dev/null +++ b/wrapdb/cimplog/meson.build @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +project('cimplog', 'c', + version: '0.0.1', + meson_version: '>=0.54.0', + license: ['Apache-2.0'], + default_options: ['c_std=c18']) + +libcimplog_dep = declare_dependency(include_directories: ['src/']) diff --git a/wrapdb/jansson/meson.build b/wrapdb/jansson/meson.build new file mode 100644 index 0000000..444bf66 --- /dev/null +++ b/wrapdb/jansson/meson.build @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +project('jansson', 'c', + version: '0.0.1', + meson_version: '>=0.54.0', + license: ['Apache-2.0'], + default_options: ['c_std=c18']) + +libjansson_dep = declare_dependency(include_directories: ['src/']) diff --git a/wrapdb/rbus/include-workaround-meson/rbus/meson.build b/wrapdb/rbus/include-workaround-meson/rbus/meson.build new file mode 100644 index 0000000..4e14b07 --- /dev/null +++ b/wrapdb/rbus/include-workaround-meson/rbus/meson.build @@ -0,0 +1,13 @@ +# This is a workaround for creating a rbus/ folder with the headers in it in +# the builddir space. +# +# See https://github.com/mesonbuild/meson/issues/2546 for where the technique comes from +# +# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +foreach h: headers + configure_file(copy: true, + input: h, + output: '@PLAINNAME@') +endforeach diff --git a/wrapdb/rbus/include/meson.build b/wrapdb/rbus/include/meson.build new file mode 100644 index 0000000..1603b34 --- /dev/null +++ b/wrapdb/rbus/include/meson.build @@ -0,0 +1,9 @@ +# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +headers = files('rbus_filter.h', + 'rbus.h', + 'rbus_message.h', + 'rbus_object.h', + 'rbus_property.h', + 'rbus_value.h') diff --git a/wrapdb/rbus/meson.build b/wrapdb/rbus/meson.build new file mode 100644 index 0000000..8cc2108 --- /dev/null +++ b/wrapdb/rbus/meson.build @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +project('rbus', 'c', + version: '0.0.1', + meson_version: '>=0.54.0', + license: ['Apache-2.0'], + default_options: ['c_std=c18']) + +subdir('include') +subdir('include-workaround-meson/rbus') + +librbus_dep = declare_dependency(include_directories: ['include-workaround-meson', + 'include-workaround-meson/rbus']) diff --git a/wrapdb/rbuscore/meson.build b/wrapdb/rbuscore/meson.build new file mode 100644 index 0000000..c4b8af0 --- /dev/null +++ b/wrapdb/rbuscore/meson.build @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +project('rbuscore', 'c', + version: '0.0.1', + meson_version: '>=0.54.0', + license: ['Apache-2.0'], + default_options: ['c_std=c18']) + + +librbuscore_dep = declare_dependency(include_directories: ['rbus-core/include']) diff --git a/wrapdb/rtMessage/include-workaround-meson/rtmessage/meson.build b/wrapdb/rtMessage/include-workaround-meson/rtmessage/meson.build new file mode 100644 index 0000000..958aaed --- /dev/null +++ b/wrapdb/rtMessage/include-workaround-meson/rtmessage/meson.build @@ -0,0 +1,13 @@ +# This is a workaround for creating a rtmessage/ folder with the headers in it in +# the builddir space. +# +# See https://github.com/mesonbuild/meson/issues/2546 for where the technique comes from +# +# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +foreach h: headers + configure_file(copy: true, + input: h, + output: '@PLAINNAME@') +endforeach diff --git a/wrapdb/rtMessage/meson.build b/wrapdb/rtMessage/meson.build new file mode 100644 index 0000000..36e1e2a --- /dev/null +++ b/wrapdb/rtMessage/meson.build @@ -0,0 +1,56 @@ +# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +project('rtMessage', 'c', + version: '0.0.1', + meson_version: '>=0.54.0', + license: ['Apache-2.0'], + default_options: ['c_std=c18']) + + +libcjson_dep = dependency('libcjson', version: '>=1.7.14', fallback: ['cjson']) +thread_dep = dependency('threads') + +headers = files('rtMessage.h', + 'rtMessageHeader.h', + 'rtError.h', + 'rtConnection.h', + 'rtVector.h', + 'rtRetainable.h', + 'rtLog.h', + 'rtList.h', + 'rtTime.h', + 'rtAtomic.h', + 'rtm_discovery_api.h', + 'rtAdvisory.h') + +subdir('include-workaround-meson/rtmessage') + +librtMessage = library('rtMessage', + ['rtConnection.c', + 'rtCipher.c', + 'rtLog.c', + 'rtError.c', + 'rtMessageHeader.c', + 'rtEncoder.c', + 'rtMessage.c', + 'rtSocket.c', + 'rtVector.c', + 'rtList.c', + 'rtTime.c', + 'rtSemaphore.c', + 'rtRetainable.c', + 'rtBase64.c', + 'local_benchmarking.c'], + c_args: ['-D_GNU_SOURCE', '-D_POSIX_C_SOURCE=199309L'], + cpp_args: ['-D_GNU_SOURCE', '-D_POSIX_C_SOURCE=199309L'], + dependencies: [ libcjson_dep, thread_dep ], + install: true) + +librtMessage_dep = declare_dependency(include_directories: ['include-workaround-meson', + 'include-workaround-meson/rtmessage'], + link_with: librtMessage) + +if meson.version().version_compare('>=0.54.0') + meson.override_dependency('librtMessage', librtMessage_dep) +endif diff --git a/wrapdb/wdmp/meson.build b/wrapdb/wdmp/meson.build new file mode 100644 index 0000000..5ee5aa3 --- /dev/null +++ b/wrapdb/wdmp/meson.build @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +project('wdmp', 'c', + version: '0.0.1', + meson_version: '>=0.54.0', + license: ['Apache-2.0'], + default_options: ['c_std=c18']) + +libwdmp_dep = declare_dependency(include_directories: ['src/'])