1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
|
/**
* @file rpc_subscribe_example.c
* @author Michal Vasko <mvasko@cesnet.cz>
* @brief example of an application subscribing to an RPC
*
* @copyright
* Copyright (c) 2019 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*/
#define _GNU_SOURCE
#define _XOPEN_SOURCE 500
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <inttypes.h>
#include <libyang/libyang.h>
#include "sysrepo.h"
volatile int exit_application = 0;
static void
print_val(const sr_val_t *value)
{
if (NULL == value) {
return;
}
printf("%s ", value->xpath);
switch (value->type) {
case SR_CONTAINER_T:
case SR_CONTAINER_PRESENCE_T:
printf("(container)");
break;
case SR_LIST_T:
printf("(list instance)");
break;
case SR_STRING_T:
printf("= %s", value->data.string_val);
break;
case SR_BOOL_T:
printf("= %s", value->data.bool_val ? "true" : "false");
break;
case SR_DECIMAL64_T:
printf("= %g", value->data.decimal64_val);
break;
case SR_INT8_T:
printf("= %" PRId8, value->data.int8_val);
break;
case SR_INT16_T:
printf("= %" PRId16, value->data.int16_val);
break;
case SR_INT32_T:
printf("= %" PRId32, value->data.int32_val);
break;
case SR_INT64_T:
printf("= %" PRId64, value->data.int64_val);
break;
case SR_UINT8_T:
printf("= %" PRIu8, value->data.uint8_val);
break;
case SR_UINT16_T:
printf("= %" PRIu16, value->data.uint16_val);
break;
case SR_UINT32_T:
printf("= %" PRIu32, value->data.uint32_val);
break;
case SR_UINT64_T:
printf("= %" PRIu64, value->data.uint64_val);
break;
case SR_IDENTITYREF_T:
printf("= %s", value->data.identityref_val);
break;
case SR_INSTANCEID_T:
printf("= %s", value->data.instanceid_val);
break;
case SR_BITS_T:
printf("= %s", value->data.bits_val);
break;
case SR_BINARY_T:
printf("= %s", value->data.binary_val);
break;
case SR_ENUM_T:
printf("= %s", value->data.enum_val);
break;
case SR_LEAF_EMPTY_T:
printf("(empty leaf)");
break;
default:
printf("(unprintable)");
break;
}
switch (value->type) {
case SR_UNKNOWN_T:
case SR_CONTAINER_T:
case SR_CONTAINER_PRESENCE_T:
case SR_LIST_T:
case SR_LEAF_EMPTY_T:
printf("\n");
break;
default:
printf("%s\n", value->dflt ? " [default]" : "");
break;
}
}
static int
rpc_cb(sr_session_ctx_t *session, const char *path, const sr_val_t *input, const size_t input_cnt,
sr_event_t event, uint32_t request_id, sr_val_t **output, size_t *output_cnt, void *private_data)
{
size_t i;
(void)session;
(void)event;
(void)request_id;
(void)private_data;
printf("\n\n ========== RPC \"%s\" RECEIVED: =======================\n\n", path);
for (i = 0; i < input_cnt; ++i) {
print_val(&input[i]);
}
if (!strcmp(path, "/examples:oper")) {
/* generate some output */
*output = malloc(sizeof **output);
*output_cnt = 1;
(*output)[0].xpath = strdup("/examples:oper/ret");
(*output)[0].type = SR_INT64_T;
(*output)[0].dflt = 0;
(*output)[0].data.int64_val = -123456;
}
return SR_ERR_OK;
}
static void
sigint_handler(int signum)
{
(void)signum;
exit_application = 1;
}
int
main(int argc, char **argv)
{
sr_conn_ctx_t *connection = NULL;
sr_session_ctx_t *session = NULL;
sr_subscription_ctx_t *subscription = NULL;
int rc = SR_ERR_OK;
const char *path;
if (argc != 2) {
printf("%s <path-to-rpc>\n", argv[0]);
return EXIT_FAILURE;
}
path = argv[1];
printf("Application will subscribe to \"%s\" RPC.\n\n", path);
/* turn logging on */
sr_log_stderr(SR_LL_WRN);
/* connect to sysrepo */
rc = sr_connect(0, &connection);
if (rc != SR_ERR_OK) {
goto cleanup;
}
/* start session */
rc = sr_session_start(connection, SR_DS_RUNNING, &session);
if (rc != SR_ERR_OK) {
goto cleanup;
}
/* subscribe for the RPC */
rc = sr_rpc_subscribe(session, path, rpc_cb, NULL, 0, 0, &subscription);
if (rc != SR_ERR_OK) {
goto cleanup;
}
printf("\n\n ========== LISTENING FOR RPC ==========\n\n");
/* loop until ctrl-c is pressed / SIGINT is received */
signal(SIGINT, sigint_handler);
signal(SIGPIPE, SIG_IGN);
while (!exit_application) {
sleep(1000);
}
printf("Application exit requested, exiting.\n");
cleanup:
sr_disconnect(connection);
return rc ? EXIT_FAILURE : EXIT_SUCCESS;
}
|