Skip to content

Commit f36be34

Browse files
committed
session client UPDATE enable raw message handling
1 parent 2d7a74b commit f36be34

5 files changed

Lines changed: 108 additions & 4 deletions

File tree

src/io.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,7 @@ nc_write_msg_io(struct nc_session *session, int io_timeout, int type, ...)
831831
char *buf;
832832
struct nc_wclb_arg arg;
833833
const char **capabilities;
834-
uint32_t *sid = NULL, i, wd = 0;
834+
uint32_t *sid = NULL, i, wd = 0, str_len;
835835
LY_ERR lyrc;
836836

837837
assert(session);
@@ -1042,6 +1042,16 @@ nc_write_msg_io(struct nc_session *session, int io_timeout, int type, ...)
10421042
}
10431043
break;
10441044

1045+
case NC_MSG_RAW:
1046+
str = va_arg(ap, const char *);
1047+
str_len = va_arg(ap, uint32_t);
1048+
1049+
/* write the message */
1050+
nc_write_clb((void *)&arg, str, str_len, 0);
1051+
1052+
session->opts.client.msgid++;
1053+
break;
1054+
10451055
default:
10461056
ret = NC_MSG_ERROR;
10471057
goto cleanup;

src/netconf.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ typedef enum {
7575
NC_MSG_RPC, /**< \<rpc\> message */
7676
NC_MSG_REPLY, /**< \<rpc-reply\> message */
7777
NC_MSG_REPLY_ERR_MSGID, /**< \<rpc-reply\> message with missing or wrong message-id attribute value */
78-
NC_MSG_NOTIF /**< \<notification\> message */
78+
NC_MSG_NOTIF, /**< \<notification\> message */
79+
NC_MSG_RAW /**< raw string message */
7980
} NC_MSG_TYPE;
8081

8182
/**

src/session_client.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2588,6 +2588,35 @@ nc_recv_notif_dispatch_data(struct nc_session *session, nc_notif_dispatch_clb no
25882588
return 0;
25892589
}
25902590

2591+
API int
2592+
nc_recv_msg(struct nc_session *session, int timeout, char **msg)
2593+
{
2594+
struct ly_in *msg_in = NULL;
2595+
NC_MSG_TYPE ret;
2596+
ly_bool msg_destroy = 1;
2597+
2598+
NC_CHECK_ARG_RET(session, session, msg, NC_MSG_ERROR);
2599+
2600+
if ((session->status != NC_STATUS_RUNNING) || (session->side != NC_CLIENT)) {
2601+
ERR(session, "Invalid session to receive RPC replies.");
2602+
return NC_MSG_ERROR;
2603+
}
2604+
2605+
/* receive a message */
2606+
ret = recv_msg(session, timeout, NC_MSG_REPLY, &msg_in);
2607+
if (ret != NC_MSG_REPLY) {
2608+
goto cleanup;
2609+
}
2610+
2611+
/* get the message string */
2612+
*msg = (char *)ly_in_memory(msg_in, NULL);
2613+
msg_destroy = 0;
2614+
2615+
cleanup:
2616+
ly_in_free(msg_in, msg_destroy);
2617+
return ret;
2618+
}
2619+
25912620
void
25922621
nc_client_notification_threads_stop(struct nc_session *session)
25932622
{
@@ -3242,6 +3271,33 @@ nc_send_rpc(struct nc_session *session, struct nc_rpc *rpc, int timeout, uint64_
32423271
return r;
32433272
}
32443273

3274+
API NC_MSG_TYPE
3275+
nc_send_msg(struct nc_session *session, const char *msg, uint32_t msg_len, int timeout, uint64_t *msgid)
3276+
{
3277+
NC_MSG_TYPE r;
3278+
uint64_t cur_msgid;
3279+
3280+
NC_CHECK_ARG_RET(session, session, msg, NC_MSG_ERROR);
3281+
3282+
if ((session->status != NC_STATUS_RUNNING) || (session->side != NC_CLIENT)) {
3283+
ERR(session, "Invalid session to send RPCs.");
3284+
return NC_MSG_ERROR;
3285+
}
3286+
3287+
if (!msg_len) {
3288+
msg_len = strlen(msg);
3289+
}
3290+
3291+
/* send RPC, store its message ID */
3292+
r = nc_write_msg_io(session, timeout, NC_MSG_RAW, msg, msg_len);
3293+
cur_msgid = session->opts.client.msgid;
3294+
3295+
if (msgid && (r == NC_MSG_RPC)) {
3296+
*msgid = cur_msgid;
3297+
}
3298+
return r;
3299+
}
3300+
32453301
API void
32463302
nc_client_session_set_not_strict(struct nc_session *session)
32473303
{

src/session_client.h

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -500,8 +500,6 @@ int nc_session_ntf_thread_running(const struct nc_session *session);
500500
/**
501501
* @brief Receive NETCONF RPC reply.
502502
*
503-
* @note This function can be called in a single thread only.
504-
*
505503
* @param[in] session NETCONF session from which the function gets data. It must be the
506504
* client side session object.
507505
* @param[in] rpc Original RPC this should be the reply to.
@@ -575,6 +573,24 @@ int nc_recv_notif_dispatch(struct nc_session *session, nc_notif_dispatch_clb not
575573
int nc_recv_notif_dispatch_data(struct nc_session *session, nc_notif_dispatch_clb notif_clb, void *user_data,
576574
void (*free_data)(void *));
577575

576+
/**
577+
* @brief Receive a reply message.
578+
*
579+
* Allows receiving raw NETCONF messages and does not perform any checks including message-id matching.
580+
* For all valid messages, ::nc_recv_reply() should be used instead.
581+
*
582+
* @param[in] session NETCONF session from which the function gets data. It must be the
583+
* client side session object.
584+
* @param[in] timeout Timeout for reading in milliseconds. Use negative value for infinite
585+
* waiting and 0 for immediate return if data are not available on the wire.
586+
* @param[out] msg Received message as a string.
587+
* @return #NC_MSG_REPLY for success,
588+
* #NC_MSG_WOULDBLOCK if @p timeout has elapsed,
589+
* #NC_MSG_ERROR if reading has failed,
590+
* #NC_MSG_NOTIF if a notification was read instead (call this function again to get the reply).
591+
*/
592+
int nc_recv_msg(struct nc_session *session, int timeout, char **msg);
593+
578594
/**
579595
* @brief Send NETCONF RPC message via the session.
580596
*
@@ -589,6 +605,24 @@ int nc_recv_notif_dispatch_data(struct nc_session *session, nc_notif_dispatch_cl
589605
*/
590606
NC_MSG_TYPE nc_send_rpc(struct nc_session *session, struct nc_rpc *rpc, int timeout, uint64_t *msgid);
591607

608+
/**
609+
* @brief Send a message via the session.
610+
*
611+
* Allows for sending arbitrary NETCONF-encoded messages. For all valid messages, ::nc_send_rpc() should be used
612+
* instead.
613+
*
614+
* @param[in] session NETCONF session where the RPC will be written.
615+
* @param[in] msg Message (XML-encoded) to send.
616+
* @param[in] msg_len Length of @p msg. May be 0 if it is 0-terminated.
617+
* @param[in] timeout Timeout for writing in milliseconds. Use negative value for infinite
618+
* waiting and 0 for return if data cannot be sent immediately.
619+
* @param[out] msgid Optional, if RPC was successfully sent, this is it's message ID.
620+
* @return #NC_MSG_RPC on success,
621+
* #NC_MSG_WOULDBLOCK in case of a busy session, and
622+
* #NC_MSG_ERROR on error.
623+
*/
624+
NC_MSG_TYPE nc_send_msg(struct nc_session *session, const char *msg, uint32_t msg_len, int timeout, uint64_t *msgid);
625+
592626
/**
593627
* @brief Make a session not strict when sending RPCs and receiving RPC replies. In other words,
594628
* it will silently skip unknown nodes without an error.

src/session_p.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,6 +1562,9 @@ int nc_write_clb(struct nc_wclb_arg *arg, const void *buf, uint32_t count, int x
15621562
* - #NC_MSG_HELLO
15631563
* - `const char **capabs;` - capabilities array ended with NULL. Required parameter.
15641564
* - `uint32_t *sid;` - session ID to be included in the hello message. Optional parameter.
1565+
* - #NC_MSG_RAW
1566+
* - `const char *msg;` - string message to print. Required parameter.
1567+
* - `uint32_t msg_len;` - message length. Required parameter.
15651568
*
15661569
* @return Type of the written message. #NC_MSG_WOULDBLOCK is returned if timeout is positive
15671570
* (or zero) value and IO lock could not be acquired in that time. #NC_MSG_ERROR is

0 commit comments

Comments
 (0)