diff --git a/include/wrp-c/rbus.h b/include/wrp-c/rbus.h new file mode 100644 index 0000000..86b5767 --- /dev/null +++ b/include/wrp-c/rbus.h @@ -0,0 +1,49 @@ +/* SPDX-FileCopyrightText: 2022 Comcast Cable Communications Management, LLC */ +/* SPDX-License-Identifier: Apache-2.0 */ +#ifndef __WRPC_RBUS_H__ +#define __WRPC_RBUS_H__ + +#include "wrp-c.h" +#include +#include +#include + +/** + * Converts a wrp structure to an rbus encoded form. + * + * @param src the message to encode + * @param dest If *dest != NULL then encode into the specified buffer. + * If *dest == NULL then the function will allocate a buffer and + * return a pointer to it here. + * @param len The dest buffer length if provided, and the number of valid + * encoded byte in dest. + * + * @retval WRPE_OK + * @retval WRPE_INVALID_ARGS + * @retval WRPE_NOT_A_WRP_MSG + * @retval WRPE_MSG_TOO_BIG + * @retval WRPE_OUT_OF_MEMORY + * @retval WRPE_OTHER_ERROR + */ +WRPcode wrp_to_rbus(const wrp_msg_t *src, rbusObject_t *dest); + + +/** + * Converts an rbus encoded message into the wrp c structure. + * + * @note All data is copied from the rbus objects because it does not + * provide a way to reference the information directly and safely. + * + * @param src the rbusObject_t object + * @param dest the resulting object (must be released by caller) + * + * @retval WRPE_OK + * @retval WRPE_INVALID_ARGS + * @retval WRPE_NOT_MSGPACK_FORMAT + * @retval WRPE_NOT_A_WRP_MSG + * @retval WRPE_MSG_TOO_BIG + * @retval WRPE_OUT_OF_MEMORY + * @retval WRPE_OTHER_ERROR + */ +WRPcode wrp_from_rbus(const rbusObject_t src, wrp_msg_t **dest); +#endif diff --git a/include/wrp-c/wrp-c.h b/include/wrp-c/wrp-c.h index b1ec88c..405934f 100644 --- a/include/wrp-c/wrp-c.h +++ b/include/wrp-c/wrp-c.h @@ -134,7 +134,9 @@ struct wrp_event_msg { struct wrp_string msg_id; /* Optional */ struct wrp_string_list partner_ids; /* Optional */ struct wrp_blob payload; /* Optional */ + struct wrp_int rdr; /* Optional */ struct wrp_string session_id; /* Optional */ + struct wrp_string trans_id; /* Optional */ }; struct wrp_crud_msg { diff --git a/meson.build b/meson.build index 4ba6dfe..675731d 100644 --- a/meson.build +++ b/meson.build @@ -1,12 +1,12 @@ # Meson build file # -# SPDX-FileCopyrightText: 2021 Comcast Cable Communications Management, LLC +# SPDX-FileCopyrightText: 2021-2022 Comcast Cable Communications Management, LLC # SPDX-License-Identifier: Apache-2.0 project('wrp-c', 'c', version: '2.0.0', license: ['Apache-2.0'], - default_options: ['c_std=c99', + default_options: ['c_std=c11', 'b_coverage=true']) if not meson.is_subproject() @@ -33,17 +33,22 @@ subdir('include/'+meson.project_name()) ludocode_mpack_dep = dependency('mpack', version: '>=1.0', fallback: ['ludocode-mpack', 'ludocode_mpack_dep'], ) -cutils_dep = dependency('cutils', version: '>=1.0.0') +cutils_dep = dependency('cutils', version: '>=1.0.0') all_deps = [ludocode_mpack_dep, cutils_dep] +if get_option('rbus-support') + librbus_dep = dependency('librbus') + all_deps += [librbus_dep] +endif + ################################################################################ # Define the libraries ################################################################################ inc = include_directories([inc_base]) -install_headers([inc_base+'/wrp-c.h', ver_h], subdir: meson.project_name()) +headers = [inc_base+'/wrp-c.h', ver_h] sources = [ 'src/constants.c', 'src/decode.c', @@ -52,6 +57,13 @@ sources = [ 'src/constants.c', 'src/locator.c', 'src/string.c'] +if get_option('rbus-support') + sources += [ 'src/rbus.c' ] + headers += [ inc_base+'/rbus.h' ] +endif + +install_headers(headers, subdir: meson.project_name()) + libwrpc = library(meson.project_name(), sources, include_directories: inc, diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000..cb5bdf6 --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,12 @@ +# -*- mode: meson -*- +# SPDX-FileCopyrightText: 2022 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 + +#################################################### +# Under each section keep the options alphabetized # +#################################################### + +# Build configuration options +#------------------------------------------------------------------------------- +option('rbus-support', type: 'boolean', value: 'true', + description: 'build the rbus compatability code') diff --git a/src/rbus.c b/src/rbus.c new file mode 100644 index 0000000..ddfe7d6 --- /dev/null +++ b/src/rbus.c @@ -0,0 +1,278 @@ +/* SPDX-FileCopyrightText: 2022 Comcast Cable Communications Management, LLC */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include +#include + +#include "../include/wrp-c/rbus.h" +#include "constants.h" + +/*----------------------------------------------------------------------------*/ +/* Macros */ +/*----------------------------------------------------------------------------*/ +/* none */ + +/*----------------------------------------------------------------------------*/ +/* Data Structures */ +/*----------------------------------------------------------------------------*/ +/* none */ + +/*----------------------------------------------------------------------------*/ +/* File Scoped Variables */ +/*----------------------------------------------------------------------------*/ +/* none */ + +/*----------------------------------------------------------------------------*/ +/* Function Prototypes */ +/*----------------------------------------------------------------------------*/ +/* none */ + +/*----------------------------------------------------------------------------*/ +/* Internal functions */ +/*----------------------------------------------------------------------------*/ +static WRPcode add_int___(rbusObject_t obj, const char *name, const struct wrp_int *i, WRPcode *err) +{ + if (WRPE_OK != *err) { + return *err; + } + + if (i) { + rbusValue_t value = rbusValue_FromInt32((int32_t) *i->num); + + if (value) { + rbusObject_SetValue(obj, name, value); + } else { + *err = WRPE_OUT_OF_MEMORY; + } + } + + return *err; +} + + +static WRPcode add_bytes_(rbusObject_t obj, const char *name, const struct wrp_blob *b, WRPcode *err) +{ + if (WRPE_OK != *err) { + return *err; + } + + if (b && (0 < b->len)) { + rbusValue_t value = rbusValue_FromBytes(b->data, (int) b->len); + if (value) { + rbusObject_SetValue(obj, name, value); + } else { + *err = WRPE_OUT_OF_MEMORY; + } + } + + return *err; +} + + +static WRPcode add_string(rbusObject_t obj, const char *name, const struct wrp_string *s, WRPcode *err) +{ + if (WRPE_OK != *err) { + return *err; + } + + if (s && (0 < s->len)) { + char *str = cu_strndup(s->s, s->len); + + if (str) { + rbusValue_t value = rbusValue_FromString(str); + + if (value) { + rbusObject_SetValue(obj, name, value); + } else { + *err = WRPE_OUT_OF_MEMORY; + } + + free(str); + } else { + *err = WRPE_OUT_OF_MEMORY; + } + } + + return *err; +} + + +static WRPcode add_msg_type(rbusObject_t obj, const char *type, WRPcode *err) +{ + if (WRPE_OK != *err) { + return *err; + } + + rbusValue_t value = rbusValue_FromString(type); + + if (value) { + rbusObject_SetValue(obj, WRP_MSG_TYPE.s, value); + } else { + *err = WRPE_OUT_OF_MEMORY; + } + + return *err; +} + + +static WRPcode handle_auth(rbusObject_t obj, const struct wrp_auth_msg *auth) +{ + WRPcode err = WRPE_OK; + + return add_int___(obj, WRP_STATUS__.s, &auth->status, &err); +} + + +static WRPcode handle_req(rbusObject_t obj, const struct wrp_req_msg *req) +{ + WRPcode err = WRPE_OK; + + add_string(obj, WRP_DEST____.s, &req->dest, &err); + add_string(obj, WRP_SOURCE__.s, &req->source, &err); + add_bytes_(obj, WRP_PAYLOAD_.s, &req->payload, &err); + add_string(obj, WRP_TRANS_ID.s, &req->trans_id, &err); + add_string(obj, WRP_ACCEPT__.s, &req->accept, &err); + add_string(obj, WRP_CT______.s, &req->content_type, &err); + // headers + // metadata + add_string(obj, WRP_MSG_ID__.s, &req->msg_id, &err); + // partners + add_int___(obj, WRP_RDR_____.s, &req->rdr, &err); + add_string(obj, WRP_SESS_ID_.s, &req->session_id, &err); + add_int___(obj, WRP_STATUS__.s, &req->status, &err); + + return err; +} + + +static WRPcode handle_event(rbusObject_t obj, const struct wrp_event_msg *e) +{ + WRPcode err = WRPE_OK; + + add_string(obj, WRP_DEST____.s, &e->dest, &err); + add_string(obj, WRP_SOURCE__.s, &e->source, &err); + add_string(obj, WRP_CT______.s, &e->content_type, &err); + // headers + // metadata + add_string(obj, WRP_MSG_ID__.s, &e->msg_id, &err); + // partners + add_bytes_(obj, WRP_PAYLOAD_.s, &e->payload, &err); + add_string(obj, WRP_SESS_ID_.s, &e->session_id, &err); + add_string(obj, WRP_TRANS_ID.s, &e->trans_id, &err); + add_int___(obj, WRP_RDR_____.s, &e->rdr, &err); + + return err; +} + + +static WRPcode handle_crud(rbusObject_t obj, const struct wrp_crud_msg *crud) +{ + WRPcode err = WRPE_OK; + + add_string(obj, WRP_DEST____.s, &crud->dest, &err); + add_string(obj, WRP_SOURCE__.s, &crud->source, &err); + add_string(obj, WRP_TRANS_ID.s, &crud->trans_id, &err); + + add_string(obj, WRP_ACCEPT__.s, &crud->accept, &err); + add_string(obj, WRP_CT______.s, &crud->content_type, &err); + // headers + // metadata + add_string(obj, WRP_MSG_ID__.s, &crud->msg_id, &err); + // partners + add_string(obj, WRP_PATH____.s, &crud->path, &err); + add_bytes_(obj, WRP_PAYLOAD_.s, &crud->payload, &err); + add_int___(obj, WRP_RDR_____.s, &crud->rdr, &err); + add_string(obj, WRP_SESS_ID_.s, &crud->session_id, &err); + add_int___(obj, WRP_STATUS__.s, &crud->status, &err); + + return err; +} + + +static WRPcode handle_reg(rbusObject_t obj, const struct wrp_svc_reg_msg *reg) +{ + WRPcode err = WRPE_OK; + + add_string(obj, WRP_SN______.s, ®->service_name, &err); + add_string(obj, WRP_URL_____.s, ®->service_name, &err); + + return err; +} + +/*----------------------------------------------------------------------------*/ +/* External Functions */ +/*----------------------------------------------------------------------------*/ + +WRPcode wrp_to_rbus(const wrp_msg_t *src, rbusObject_t *dest) +{ + const char *msg_type; + WRPcode err = WRPE_OK; + + if (!dest || !src) { + return WRPE_INVALID_ARGS; + } + + rbusObject_Init(dest, NULL); + rbusObject_SetName(*dest, "wrp"); + + switch (src->msg_type) { + case WRP_MSG_TYPE__AUTH: + msg_type = "auth"; + err = handle_auth(*dest, &src->u.auth); + break; + case WRP_MSG_TYPE__REQ: + msg_type = "reqresp"; + err = handle_req(*dest, &src->u.req); + break; + case WRP_MSG_TYPE__EVENT: + msg_type = "event"; + err = handle_event(*dest, &src->u.event); + break; + case WRP_MSG_TYPE__CREATE: + msg_type = "create"; + err = handle_crud(*dest, &src->u.crud); + break; + case WRP_MSG_TYPE__RETRIEVE: + msg_type = "retrieve"; + err = handle_crud(*dest, &src->u.crud); + break; + case WRP_MSG_TYPE__UPDATE: + msg_type = "update"; + err = handle_crud(*dest, &src->u.crud); + break; + case WRP_MSG_TYPE__DELETE: + msg_type = "delete"; + err = handle_crud(*dest, &src->u.crud); + break; + case WRP_MSG_TYPE__SVC_REG: + msg_type = "svc_reg"; + err = handle_reg(*dest, &src->u.reg); + break; + case WRP_MSG_TYPE__SVC_ALIVE: + msg_type = "svc_alive"; + break; + default: + return WRPE_INVALID_ARGS; + } + + add_msg_type(*dest, msg_type, &err); + + if (WRPE_OK != err) { + // TODO Cleanup + } + + return err; +} + + +WRPcode wrp_from_rbus(const rbusObject_t src, wrp_msg_t **dest) +{ + // TODO for now + (void) src; + (void) dest; + + return WRPE_OK; +} diff --git a/subprojects/packagefiles/rbus/include-workaround-meson/rbus/meson.build b/subprojects/packagefiles/rbus/include-workaround-meson/rbus/meson.build new file mode 100644 index 0000000..c9ecfcc --- /dev/null +++ b/subprojects/packagefiles/rbus/include-workaround-meson/rbus/meson.build @@ -0,0 +1,9 @@ +# 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 +foreach h: headers + configure_file(copy: true, + input: h, + output: '@PLAINNAME@') +endforeach diff --git a/subprojects/packagefiles/rbus/include/meson.build b/subprojects/packagefiles/rbus/include/meson.build new file mode 100644 index 0000000..1a58d74 --- /dev/null +++ b/subprojects/packagefiles/rbus/include/meson.build @@ -0,0 +1,6 @@ +headers = files('rbus_filter.h', + 'rbus.h', + 'rbus_message.h', + 'rbus_object.h', + 'rbus_property.h', + 'rbus_value.h') diff --git a/subprojects/packagefiles/rbus/meson.build b/subprojects/packagefiles/rbus/meson.build new file mode 100644 index 0000000..0e66081 --- /dev/null +++ b/subprojects/packagefiles/rbus/meson.build @@ -0,0 +1,11 @@ +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/subprojects/rbus.wrap b/subprojects/rbus.wrap new file mode 100644 index 0000000..1a7f7a4 --- /dev/null +++ b/subprojects/rbus.wrap @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2022 Comcast Cable Communications Management, LLC +# SPDX-License-Identifier: Apache-2.0 +[wrap-git] +directory = rbus + +url = https://github.com/rdkcmf/rbus.git +revision = rdk-next +patch_directory = rbus + +[provide] +librbus = librbus_dep