diff --git a/msg.c b/msg.c index 1d08981..a4a44fd 100644 --- a/msg.c +++ b/msg.c @@ -295,6 +295,40 @@ void msg_cleanup(void) } } +struct ptp_message *msg_duplicate(struct ptp_message *msg, int cnt) +{ + struct ptp_message *dup; + int err; + + dup = msg_allocate(); + if (!dup) { + return NULL; + } + memcpy(dup, msg, sizeof(*dup)); + dup->refcnt = 1; + TAILQ_INIT(&dup->tlv_list); + dup->tlv_count = 0; + + err = msg_post_recv(dup, cnt); + if (err) { + switch (err) { + case -EBADMSG: + pr_err("msg_duplicate: bad message"); + break; + case -ETIME: + pr_err("msg_duplicate: received %s without timestamp", + msg_type_string(msg_type(msg))); + break; + case -EPROTO: + pr_debug("msg_duplicate: ignoring message"); + break; + } + msg_put(dup); + return NULL; + } + return dup; +} + void msg_get(struct ptp_message *m) { m->refcnt++; diff --git a/msg.h b/msg.h index f41a0e7..38d16ef 100644 --- a/msg.h +++ b/msg.h @@ -316,6 +316,26 @@ struct ptp_message *msg_allocate(void); */ void msg_cleanup(void); +/** + * Duplicate a message instance. + * + * This function accepts a message in network byte order and returns a + * duplicate in host byte. + * + * Messages are reference counted, and newly allocated messages have a + * reference count of one. Allocated messages are freed using the + * function @ref msg_put(). + * + * @param msg A message obtained using @ref msg_allocate(). + * The passed message must be in network byte order, not + * having been passed to @ref msg_post_recv(). + * + * @return Pointer to a message on success, NULL otherwise. + * The returned message will be in host byte order, having + * been passed to @ref msg_post_recv(). + */ +struct ptp_message *msg_duplicate(struct ptp_message *msg, int cnt); + /** * Obtain a reference to a message, increasing its reference count by one. * @param m A message obtained using @ref msg_allocate().