Extend doc of RMR python binding methods
Also add type hints to function definitions
No functional changes
Issue-ID: RIC-228
Signed-off-by: Lott, Christopher (cl778h) <cl778h@att.com>
Change-Id: I709a30a1bf3b3ab52701430ac0f9c01df6dea9d7
diff --git a/ricxappframe/rmr/rmr.py b/ricxappframe/rmr/rmr.py
index 39a0245..80617a7 100644
--- a/ricxappframe/rmr/rmr.py
+++ b/ricxappframe/rmr/rmr.py
@@ -1,4 +1,3 @@
-# vim: expandtab ts=4 sw=4:
# ==================================================================================
# Copyright (c) 2019-2020 Nokia
# Copyright (c) 2018-2020 AT&T Intellectual Property.
@@ -17,16 +16,14 @@
# ==================================================================================
import uuid
import json
-from ctypes import RTLD_GLOBAL, Structure, c_int, POINTER, c_char, c_char_p, c_void_p, memmove, cast
-from ctypes import CDLL
-from ctypes import create_string_buffer
+from ctypes import CDLL, POINTER, RTLD_GLOBAL, Structure
+from ctypes import c_char, c_char_p, c_int, c_void_p, cast, create_string_buffer, memmove
+
from ricxappframe.rmr.exceptions import BadBufferAllocation, MeidSizeOutOfRange, InitFailed
# https://docs.python.org/3.7/library/ctypes.html
# https://stackoverflow.com/questions/2327344/ctypes-loading-a-c-shared-library-that-has-dependencies/30845750#30845750
# make sure you do a set -x LD_LIBRARY_PATH /usr/local/lib/;
-
-# even though we don't use these directly, they contain symbols we need
rmr_c_lib = CDLL("librmr_si.so", mode=RTLD_GLOBAL)
@@ -38,9 +35,9 @@
_rmr_const.restype = c_char_p
-def _get_constants(cache={}):
+def _get_constants(cache={}) -> dict:
"""
- Get or build needed constants from rmr
+ Gets constants published by RMR and caches for subsequent calls.
TODO: are there constants that end user applications need?
"""
if cache:
@@ -51,9 +48,10 @@
return cache
-def _get_mapping_dict(cache={}):
+def _get_mapping_dict(cache={}) -> dict:
"""
- Get or build the state mapping dict
+ Builds a state mapping dict from constants and caches for subsequent calls.
+ Relevant constants at this writing include:
RMR_OK 0 state is good
RMR_ERR_BADARG 1 argument passd to function was unusable
@@ -85,9 +83,10 @@
return cache
-def _state_to_status(stateno):
+def _state_to_status(stateno: int) -> str:
"""
- Convert a msg state to status
+ Converts a msg state integer to a status string.
+ Returns "UNKNOWN STATE" if the int value is not known.
"""
sdict = _get_mapping_dict()
@@ -105,17 +104,23 @@
# These constants are directly usable by importers of this library
# TODO: Are there others that will be useful?
+#: Maximum size message to receive
RMR_MAX_RCV_BYTES = _RCONST["RMR_MAX_RCV_BYTES"]
+#: Multi-threaded initialization flag
RMRFL_MTCALL = _RCONST.get("RMRFL_MTCALL", 0x02) # initialization flags
+#: Empty flag
RMRFL_NONE = _RCONST.get("RMRFL_NONE", 0x0)
-RMR_OK = _RCONST["RMR_OK"] # useful state constants
+#: State constant for OK
+RMR_OK = _RCONST["RMR_OK"]
+#: State constant for timeout
RMR_ERR_TIMEOUT = _RCONST["RMR_ERR_TIMEOUT"]
+#: State constant for retry
RMR_ERR_RETRY = _RCONST["RMR_ERR_RETRY"]
class rmr_mbuf_t(Structure):
"""
- Reimplementation of rmr_mbuf_t which is in an unaccessible header file (src/common/include/rmr.h)
+ Mirrors public members of type rmr_mbuf_t from RMR header file src/common/include/rmr.h
| typedef struct {
| int state; // state of processing
@@ -135,21 +140,19 @@
| int alloc_len; // the length of the allocated space (hdr+payload)
| } rmr_mbuf_t;
- We do not include the fields we are not supposed to mess with
-
RE PAYLOADs type below, see the documentation for c_char_p:
class ctypes.c_char_p
- Represents the C char * datatype when it points to a zero-terminated string. For a general character pointer that may also point to binary data, POINTER(c_char) must be used. The constructor accepts an integer address, or a bytes object.
+ Represents the C char * datatype when it points to a zero-terminated string.
+ For a general character pointer that may also point to binary data, POINTER(c_char)
+ must be used. The constructor accepts an integer address, or a bytes object.
"""
_fields_ = [
("state", c_int),
("mtype", c_int),
("len", c_int),
- (
- "payload",
- POINTER(c_char),
- ), # according to th following the python bytes are already unsinged https://bytes.com/topic/python/answers/695078-ctypes-unsigned-char
+ ("payload", POINTER(c_char)), # according to the following the python bytes are already unsigned
+ # https://bytes.com/topic/python/answers/695078-ctypes-unsigned-char
("xaction", POINTER(c_char)),
("sub_id", c_int),
("tp_state", c_int),
@@ -164,13 +167,28 @@
_rmr_init.restype = c_void_p
-def rmr_init(uproto_port, max_msg_size, flags):
+def rmr_init(uproto_port: c_char_p, max_msg_size: int, flags: int) -> c_void_p:
"""
- Refer to rmr C documentation for rmr_init
- extern void* rmr_init(char* uproto_port, int max_msg_size, int flags)
+ Prepares the environment for sending and receiving messages.
+ Refer to RMR C documentation for method::
- This python function checks that the context is not None and raises
- an excption if it is.
+ extern void* rmr_init(char* uproto_port, int max_msg_size, int flags)
+
+ This function raises an exception if the returned context is None.
+
+ Parameters
+ ----------
+ uproto_port: c_char_p
+ Pointer to bytes built from the port number as a string; e.g., b'4550'
+ max_msg_size: integer
+ Maximum message size to receive
+ flags: integer
+ RMR option flags
+
+ Returns
+ -------
+ c_void_p:
+ Pointer to RMR context
"""
mrc = _rmr_init(uproto_port, max_msg_size, flags)
if mrc is None:
@@ -183,10 +201,21 @@
_rmr_ready.restype = c_int
-def rmr_ready(vctx):
+def rmr_ready(vctx: c_void_p) -> int:
"""
- Refer to rmr C documentation for rmr_ready
- extern int rmr_ready(void* vctx)
+ Checks if a routing table has been received and installed.
+ Refer to RMR C documentation for method::
+
+ extern int rmr_ready(void* vctx)
+
+ Parameters
+ ----------
+ vctx: ctypes c_void_p
+ Pointer to RMR context
+
+ Returns
+ -------
+ 1 for yes, 0 for no
"""
return _rmr_ready(vctx)
@@ -195,12 +224,23 @@
_rmr_close.argtypes = [c_void_p]
-def rmr_close(vctx):
+def rmr_close(vctx: c_void_p):
"""
- Refer to rmr C documentation for rmr_close
- extern void rmr_close(void* vctx)
+ Closes the listen socket.
+ Refer to RMR C documentation for method::
+
+ extern void rmr_close(void* vctx)
+
+ Parameters
+ ----------
+ vctx: ctypes c_void_p
+ Pointer to RMR context
+
+ Returns
+ -------
+ None
"""
- return _rmr_close(vctx)
+ _rmr_close(vctx)
_rmr_set_stimeout = rmr_c_lib.rmr_set_stimeout
@@ -208,12 +248,25 @@
_rmr_set_stimeout.restype = c_int
-def rmr_set_stimeout(vctx, time):
+def rmr_set_stimeout(vctx: c_void_p, rloops: int) -> int:
"""
- Refer to the rmr C documentation for rmr_set_stimeout
- extern int rmr_set_stimeout(void* vctx, int time)
+ Sets the configuration for how RMR will retry message send operations.
+ Refer to RMR C documentation for method::
+
+ extern int rmr_set_stimeout(void* vctx, int rloops)
+
+ Parameters
+ ----------
+ vctx: ctypes c_void_p
+ Pointer to RMR context
+ rloops: int
+ Number of retry loops
+
+ Returns
+ -------
+ 0 on success, -1 on failure
"""
- return _rmr_set_stimeout(vctx, time)
+ return _rmr_set_stimeout(vctx, rloops)
_rmr_alloc_msg = rmr_c_lib.rmr_alloc_msg
@@ -221,21 +274,44 @@
_rmr_alloc_msg.restype = POINTER(rmr_mbuf_t)
-def rmr_alloc_msg(
- vctx, size, payload=None, gen_transaction_id=False, mtype=None, meid=None, sub_id=None, fixed_transaction_id=None
-):
+def rmr_alloc_msg(vctx: c_void_p, size: int,
+ payload=None, gen_transaction_id=False, mtype=None,
+ meid=None, sub_id=None, fixed_transaction_id=None):
"""
- Refer to the rmr C documentation for rmr_alloc_msg
- extern rmr_mbuf_t* rmr_alloc_msg(void* vctx, int size)
+ Allocates and returns a buffer to write and send through the RMR library.
+ Refer to RMR C documentation for method::
+
+ extern rmr_mbuf_t* rmr_alloc_msg(void* vctx, int size)
+
+ Optionally populates the message from the remaining arguments.
+
TODO: on next API break, clean up transaction_id ugliness. Kept for now to preserve API.
- if payload is not None, attempts to set the payload
- if gen_transaction_id is True, it generates and sets a transaction id. Note, fixed_transaction_id supersedes this option
- if mtype is not None, sets the sbuf's message type
- if meid is not None, sets the sbuf's meid
- if sub_id is not None, sets the sbud's subscription id
- if fixed_transaction_id is set, it deterministically sets the transaction_id. This overrides the option gen_transation_id
+ Parameters
+ ----------
+ vctx: ctypes c_void_p
+ Pointer to RMR context
+ size: int
+ How much space to allocate
+ payload: bytes
+ if not None, attempts to set the payload
+ gen_transaction_id: bool
+ if True, generates and sets a transaction ID.
+ Note, option fixed_transaction_id overrides this option
+ mtype: bytes
+ if not None, sets the sbuf's message type
+ meid: bytes
+ if not None, sets the sbuf's meid
+ sub_id: bytes
+ if not None, sets the sbuf's subscription id
+ fixed_transaction_id: bytes
+ if not None, used as the transaction ID.
+ Note, this overrides the option gen_transaction_id
+ Returns
+ -------
+ c_void_p:
+ Pointer to rmr_mbuf structure
"""
sbuf = _rmr_alloc_msg(vctx, size)
try:
@@ -271,26 +347,55 @@
_rmr_realloc_payload.restype = POINTER(rmr_mbuf_t)
-def rmr_realloc_payload(ptr_mbuf, new_len, copy=False, clone=False):
+def rmr_realloc_payload(ptr_mbuf: c_void_p, new_len: int, copy=False, clone=False):
"""
- Refer to the rmr C documentation for rmr_realloc_payload().
- extern rmr_mbuf_t* rmr_realloc_payload(rmr_mbuf_t*, int, int, int)
+ Allocates and returns a message buffer large enough for the new length.
+ Refer to RMR C documentation for method::
+
+ extern rmr_mbuf_t* rmr_realloc_payload(rmr_mbuf_t*, int, int, int)
+
+ Parameters
+ ----------
+ ptr_mbuf: c_void_p
+ Pointer to rmr_mbuf structure
+ new_len: int
+ Length
+ copy: bool
+ Whether to copy the original paylod
+ clone: bool
+ Whether to clone the original buffer
+
+ Returns
+ -------
+ c_void_p:
+ Pointer to rmr_mbuf structure
"""
return _rmr_realloc_payload(ptr_mbuf, new_len, copy, clone)
_rmr_free_msg = rmr_c_lib.rmr_free_msg
-_rmr_free_msg.argtypes = [c_void_p]
+_rmr_free_msg.argtypes = [POINTER(rmr_mbuf_t)]
_rmr_free_msg.restype = None
-def rmr_free_msg(mbuf):
+def rmr_free_msg(ptr_mbuf: c_void_p):
"""
- Refer to the rmr C documentation for rmr_free_msg
- extern void rmr_free_msg(rmr_mbuf_t* mbuf )
+ Releases the message buffer.
+ Refer to RMR C documentation for method::
+
+ extern void rmr_free_msg(rmr_mbuf_t* mbuf )
+
+ Parameters
+ ----------
+ ptr_mbuf: c_void_p
+ Pointer to rmr_mbuf structure
+
+ Returns
+ -------
+ None
"""
- if mbuf is not None:
- _rmr_free_msg(mbuf)
+ if ptr_mbuf is not None:
+ _rmr_free_msg(ptr_mbuf)
_rmr_payload_size = rmr_c_lib.rmr_payload_size
@@ -298,10 +403,22 @@
_rmr_payload_size.restype = c_int
-def rmr_payload_size(ptr_mbuf):
+def rmr_payload_size(ptr_mbuf: c_void_p) -> int:
"""
- Refer to the rmr C documentation for rmr_payload_size
- extern int rmr_payload_size(rmr_mbuf_t* msg)
+ Gets the number of bytes available in the payload.
+ Refer to RMR C documentation for method::
+
+ extern int rmr_payload_size(rmr_mbuf_t* msg)
+
+ Parameters
+ ----------
+ ptr_mbuf: c_void_p
+ Pointer to rmr_mbuf structure
+
+ Returns
+ -------
+ int:
+ Number of bytes available
"""
return _rmr_payload_size(ptr_mbuf)
@@ -315,10 +432,24 @@
_rmr_send_msg.restype = POINTER(rmr_mbuf_t)
-def rmr_send_msg(vctx, ptr_mbuf):
+def rmr_send_msg(vctx: c_void_p, ptr_mbuf: POINTER(rmr_mbuf_t)) -> POINTER(rmr_mbuf_t):
"""
- Refer to the rmr C documentation for rmr_send_msg
- extern rmr_mbuf_t* rmr_send_msg(void* vctx, rmr_mbuf_t* msg)
+ Sends the message according to the routing table and returns an empty buffer.
+ Refer to RMR C documentation for method::
+
+ extern rmr_mbuf_t* rmr_send_msg(void* vctx, rmr_mbuf_t* msg)
+
+ Parameters
+ ----------
+ vctx: ctypes c_void_p
+ Pointer to RMR context
+ ptr_mbuf: c_void_p
+ Pointer to rmr_mbuf structure
+
+ Returns
+ -------
+ c_void_p:
+ Pointer to rmr_mbuf structure
"""
return _rmr_send_msg(vctx, ptr_mbuf)
@@ -329,10 +460,24 @@
_rmr_rcv_msg.restype = POINTER(rmr_mbuf_t)
-def rmr_rcv_msg(vctx, ptr_mbuf):
+def rmr_rcv_msg(vctx: c_void_p, ptr_mbuf: POINTER(rmr_mbuf_t)) -> POINTER(rmr_mbuf_t):
"""
- Refer to the rmr C documentation for rmr_rcv_msg
- extern rmr_mbuf_t* rmr_rcv_msg(void* vctx, rmr_mbuf_t* old_msg)
+ Waits for a message to arrive, and returns it.
+ Refer to RMR C documentation for method::
+
+ extern rmr_mbuf_t* rmr_rcv_msg(void* vctx, rmr_mbuf_t* old_msg)
+
+ Parameters
+ ----------
+ vctx: ctypes c_void_p
+ Pointer to RMR context
+ ptr_mbuf: c_void_p
+ Pointer to rmr_mbuf structure
+
+ Returns
+ -------
+ c_void_p:
+ Pointer to rmr_mbuf structure
"""
return _rmr_rcv_msg(vctx, ptr_mbuf)
@@ -342,10 +487,26 @@
_rmr_torcv_msg.restype = POINTER(rmr_mbuf_t)
-def rmr_torcv_msg(vctx, ptr_mbuf, ms_to):
+def rmr_torcv_msg(vctx: c_void_p, ptr_mbuf: POINTER(rmr_mbuf_t), ms_to: int) -> POINTER(rmr_mbuf_t):
"""
- Refer to the rmr C documentation for rmr_torcv_msg
- extern rmr_mbuf_t* rmr_torcv_msg(void* vctx, rmr_mbuf_t* old_msg, int ms_to)
+ Waits up to the timeout value for a message to arrive, and returns it.
+ Refer to RMR C documentation for method::
+
+ extern rmr_mbuf_t* rmr_torcv_msg(void* vctx, rmr_mbuf_t* old_msg, int ms_to)
+
+ Parameters
+ ----------
+ vctx: ctypes c_void_p
+ Pointer to RMR context
+ ptr_mbuf: c_void_p
+ Pointer to rmr_mbuf structure
+ ms_to: int
+ Time out value in milliseconds
+
+ Returns
+ -------
+ c_void_p:
+ Pointer to rmr_mbuf structure
"""
return _rmr_torcv_msg(vctx, ptr_mbuf, ms_to)
@@ -355,14 +516,32 @@
_rmr_rts_msg.restype = POINTER(rmr_mbuf_t)
-def rmr_rts_msg(vctx, ptr_mbuf, payload=None, mtype=None):
+def rmr_rts_msg(vctx: c_void_p, ptr_mbuf: POINTER(rmr_mbuf_t), payload=None, mtype=None) -> POINTER(rmr_mbuf_t):
"""
- Refer to the rmr C documentation for rmr_rts_msg
- extern rmr_mbuf_t* rmr_rts_msg(void* vctx, rmr_mbuf_t* msg)
+ Sends a message to the originating endpoint and returns an empty buffer.
+ Refer to RMR C documentation for method::
+
+ extern rmr_mbuf_t* rmr_rts_msg(void* vctx, rmr_mbuf_t* msg)
additional features beyond c-rmr:
if payload is not None, attempts to set the payload
if mtype is not None, sets the sbuf's message type
+
+ Parameters
+ ----------
+ vctx: ctypes c_void_p
+ Pointer to an RMR context
+ ptr_mbuf: ctypes c_void_p
+ Pointer to an RMR message buffer
+ payload: bytes
+ Payload
+ mtype: bytes
+ Message type
+
+ Returns
+ -------
+ c_void_p:
+ Pointer to rmr_mbuf structure
"""
if payload:
@@ -379,10 +558,22 @@
_rmr_call.restype = POINTER(rmr_mbuf_t)
-def rmr_call(vctx, ptr_mbuf):
+def rmr_call(vctx: c_void_p, ptr_mbuf: POINTER(rmr_mbuf_t)) -> POINTER(rmr_mbuf_t):
"""
- Refer to the rmr C documentation for rmr_call
- extern rmr_mbuf_t* rmr_call(void* vctx, rmr_mbuf_t* msg)
+ Sends a message, waits for a response and returns it.
+ Refer to RMR C documentation for method::
+
+ extern rmr_mbuf_t* rmr_call(void* vctx, rmr_mbuf_t* msg)
+
+ Parameters
+ ----------
+ ptr_mbuf: ctypes c_void_p
+ Pointer to an RMR message buffer
+
+ Returns
+ -------
+ c_void_p:
+ Pointer to rmr_mbuf structure
"""
return _rmr_call(vctx, ptr_mbuf)
@@ -392,15 +583,29 @@
_rmr_bytes2meid.restype = c_int
-def rmr_set_meid(ptr_mbuf, byte_str):
+def rmr_set_meid(ptr_mbuf: POINTER(rmr_mbuf_t), byte_str: bytes) -> int:
"""
- Refer to the rmr C documentation for rmr_bytes2meid
- extern int rmr_bytes2meid(rmr_mbuf_t* mbuf, unsigned char const* src, int len);
+ Sets the managed entity field in the message and returns the number of bytes copied.
+ Refer to RMR C documentation for method::
+
+ extern int rmr_bytes2meid(rmr_mbuf_t* mbuf, unsigned char const* src, int len);
Caution: the meid length supported in an RMR message is 32 bytes, but C applications
expect this to be a nil terminated string and thus only 31 bytes are actually available.
Raises: exceptions.MeidSizeOutOfRang
+
+ Parameters
+ ----------
+ ptr_mbuf: ctypes c_void_p
+ Pointer to an RMR message buffer
+ byte_tr: bytes
+ Managed entity ID value
+
+ Returns
+ -------
+ int:
+ number of bytes copied
"""
max = _get_constants().get("RMR_MAX_MEID", 32)
if len(byte_str) >= max:
@@ -421,19 +626,22 @@
_rmr_get_meid.restype = c_char_p
-def rmr_get_meid(ptr_mbuf):
+def rmr_get_meid(ptr_mbuf: POINTER(rmr_mbuf_t)) -> bytes:
"""
- Get the managed equipment ID (meid) from the message header.
+ Gets the managed entity ID (meid) from the message header.
+ This is a python-friendly version of RMR C method::
+
+ extern unsigned char* rmr_get_meid(rmr_mbuf_t* mbuf, unsigned char* dest);
Parameters
----------
ptr_mbuf: ctypes c_void_p
- Pointer to an rmr message buffer
+ Pointer to an RMR message buffer
Returns
-------
- string:
- meid
+ bytes:
+ Managed entity ID
"""
sz = _get_constants().get("RMR_MAX_MEID", 32) # size for buffer to fill
buf = create_string_buffer(sz)
@@ -446,21 +654,35 @@
_rmr_get_src.restype = c_char_p
-def rmr_get_src(ptr_mbuf, dest):
+def rmr_get_src(ptr_mbuf: POINTER(rmr_mbuf_t), dest: c_char_p) -> c_char_p:
"""
- Refer to the rmr C documentation for rmr_get_src
- extern unsigned char* rmr_get_src(rmr_mbuf_t* mbuf, unsigned char* dest);
+ Copies the message-source information to the buffer.
+ Refer to RMR C documentation for method::
+
+ extern unsigned char* rmr_get_src(rmr_mbuf_t* mbuf, unsigned char* dest);
+
+ Parameters
+ ----------
+ ptr_mbuf: ctypes POINTER(rmr_mbuf_t)
+ Pointer to an RMR message buffer
+ dest: ctypes c_char_p
+ Pointer to a buffer to receive the message source
+
+ Returns
+ -------
+ string:
+ message-source information
"""
return _rmr_get_src(ptr_mbuf, dest)
# Methods that exist ONLY in rmr-python, and are not wrapped methods
-# In hindsight, I wish i put these in a seperate module, but leaving this here to prevent api breakage.
+# In hindsight, I wish i put these in a separate module, but leaving this here to prevent api breakage.
-def get_payload(ptr_mbuf):
+def get_payload(ptr_mbuf: c_void_p) -> bytes:
"""
- Given a rmr_buf_t*, get it's binary payload as a bytes object
+ Gets the binary payload from the rmr_buf_t*.
Parameters
----------
@@ -478,9 +700,9 @@
return CharArr(*ptr_mbuf.contents.payload[:sz]).raw
-def get_xaction(ptr_mbuf):
+def get_xaction(ptr_mbuf: c_void_p) -> bytes:
"""
- given a rmr_buf_t*, get it's transaction id
+ Gets the transaction ID from the rmr_buf_t*.
Parameters
----------
@@ -497,9 +719,9 @@
return val[:sz]
-def message_summary(ptr_mbuf):
+def message_summary(ptr_mbuf: c_void_p) -> dict:
"""
- Returns a dict that contains the fields of a message
+ Returns a dict with the fields of an RMR message.
Parameters
----------
@@ -526,10 +748,9 @@
}
-def set_payload_and_length(byte_str, ptr_mbuf):
+def set_payload_and_length(byte_str: bytes, ptr_mbuf: c_void_p):
"""
- | Set an rmr payload and content length
- | In place method, no return
+ Sets an rmr payload and content length.
Parameters
----------
@@ -537,6 +758,10 @@
the bytes to set the payload to
ptr_mbuf: ctypes c_void_p
Pointer to an rmr message buffer
+
+ Returns
+ -------
+ None
"""
if rmr_payload_size(ptr_mbuf) < len(byte_str): # existing message payload too small
ptr_mbuf = rmr_realloc_payload(ptr_mbuf, len(byte_str), True)
@@ -545,9 +770,9 @@
ptr_mbuf.contents.len = len(byte_str)
-def generate_and_set_transaction_id(ptr_mbuf):
+def generate_and_set_transaction_id(ptr_mbuf: c_void_p):
"""
- Generate a UUID and Set an rmr transaction id to it
+ Generates a UUID and sets the RMR transaction id to it
Parameters
----------
@@ -557,9 +782,9 @@
set_transaction_id(ptr_mbuf, uuid.uuid1().hex.encode("utf-8"))
-def set_transaction_id(ptr_mbuf, tid_bytes):
+def set_transaction_id(ptr_mbuf: c_void_p, tid_bytes: bytes):
"""
- Set an rmr transaction id
+ Sets an RMR transaction id
TODO: on next API break, merge these two functions. Not done now to preserve API.
Parameters
@@ -573,9 +798,9 @@
memmove(ptr_mbuf.contents.xaction, tid_bytes, sz)
-def get_src(ptr_mbuf):
+def get_src(ptr_mbuf: c_void_p) -> str:
"""
- Get the message source (likely host:port)
+ Gets the message source (likely host:port)
Parameters
----------