Signed-off-by: Richard Cochran <[email protected]>
---
msg.c | 2 ++
tlv.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tlv.h | 36 ++++++++++++++++++++++++++++
3 files changed, 126 insertions(+)
diff --git a/msg.c b/msg.c
index 090715b..6c20c97 100644
--- a/msg.c
+++ b/msg.c
@@ -417,6 +417,7 @@ int msg_post_recv(struct ptp_message *m, int cnt)
announce_post_recv(&m->announce);
break;
case SIGNALING:
+ port_id_post_recv(&m->signaling.targetPortIdentity);
break;
case MANAGEMENT:
port_id_post_recv(&m->management.targetPortIdentity);
@@ -467,6 +468,7 @@ int msg_pre_send(struct ptp_message *m)
announce_pre_send(&m->announce);
break;
case SIGNALING:
+ port_id_pre_send(&m->signaling.targetPortIdentity);
break;
case MANAGEMENT:
port_id_pre_send(&m->management.targetPortIdentity);
diff --git a/tlv.c b/tlv.c
index 7285af7..b647160 100644
--- a/tlv.c
+++ b/tlv.c
@@ -544,6 +544,91 @@ static void org_pre_send(struct organization_tlv *org)
}
}
+static int unicast_message_type_valid(uint8_t message_type)
+{
+ message_type >>= 4;
+ switch (message_type) {
+ case ANNOUNCE:
+ case SYNC:
+ case DELAY_RESP:
+ case PDELAY_RESP:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int unicast_negotiation_post_recv(struct tlv_extra *extra)
+{
+ struct request_unicast_xmit_tlv *request;
+ struct ack_cancel_unicast_xmit_tlv *ack;
+ struct cancel_unicast_xmit_tlv *cancel;
+ struct grant_unicast_xmit_tlv *grant;
+ struct TLV *tlv = extra->tlv;
+
+ switch (tlv->type) {
+ case TLV_REQUEST_UNICAST_TRANSMISSION:
+ if (TLV_LENGTH_INVALID(tlv, request_unicast_xmit_tlv)) {
+ return -EBADMSG;
+ }
+ request = (struct request_unicast_xmit_tlv *) tlv;
+ if (!unicast_message_type_valid(request->message_type)) {
+ return -EBADMSG;
+ }
+ NTOHL(request->durationField);
+ break;
+ case TLV_GRANT_UNICAST_TRANSMISSION:
+ if (TLV_LENGTH_INVALID(tlv, grant_unicast_xmit_tlv)) {
+ return -EBADMSG;
+ }
+ grant = (struct grant_unicast_xmit_tlv *) tlv;
+ if (!unicast_message_type_valid(grant->message_type)) {
+ return -EBADMSG;
+ }
+ NTOHL(grant->durationField);
+ break;
+ case TLV_CANCEL_UNICAST_TRANSMISSION:
+ if (TLV_LENGTH_INVALID(tlv, cancel_unicast_xmit_tlv)) {
+ return -EBADMSG;
+ }
+ cancel = (struct cancel_unicast_xmit_tlv *) tlv;
+ if (!unicast_message_type_valid(cancel->message_type_flags)) {
+ return -EBADMSG;
+ }
+ break;
+ case TLV_ACKNOWLEDGE_CANCEL_UNICAST_TRANSMISSION:
+ if (TLV_LENGTH_INVALID(tlv, ack_cancel_unicast_xmit_tlv)) {
+ return -EBADMSG;
+ }
+ ack = (struct ack_cancel_unicast_xmit_tlv *) tlv;
+ if (!unicast_message_type_valid(ack->message_type_flags)) {
+ return -EBADMSG;
+ }
+ break;
+ }
+ return 0;
+}
+
+static void unicast_negotiation_pre_send(struct TLV *tlv)
+{
+ struct request_unicast_xmit_tlv *request;
+ struct grant_unicast_xmit_tlv *grant;
+
+ switch (tlv->type) {
+ case TLV_REQUEST_UNICAST_TRANSMISSION:
+ request = (struct request_unicast_xmit_tlv *) tlv;
+ HTONL(request->durationField);
+ break;
+ case TLV_GRANT_UNICAST_TRANSMISSION:
+ grant = (struct grant_unicast_xmit_tlv *) tlv;
+ HTONL(grant->durationField);
+ break;
+ case TLV_CANCEL_UNICAST_TRANSMISSION:
+ case TLV_ACKNOWLEDGE_CANCEL_UNICAST_TRANSMISSION:
+ break;
+ }
+}
+
struct tlv_extra *tlv_extra_alloc(void)
{
struct tlv_extra *extra = TAILQ_FIRST(&tlv_pool);
@@ -605,6 +690,7 @@ int tlv_post_recv(struct tlv_extra *extra)
case TLV_GRANT_UNICAST_TRANSMISSION:
case TLV_CANCEL_UNICAST_TRANSMISSION:
case TLV_ACKNOWLEDGE_CANCEL_UNICAST_TRANSMISSION:
+ result = unicast_negotiation_post_recv(extra);
break;
case TLV_PATH_TRACE:
ptt = (struct path_trace_tlv *) tlv;
@@ -654,6 +740,8 @@ void tlv_pre_send(struct TLV *tlv, struct tlv_extra *extra)
case TLV_GRANT_UNICAST_TRANSMISSION:
case TLV_CANCEL_UNICAST_TRANSMISSION:
case TLV_ACKNOWLEDGE_CANCEL_UNICAST_TRANSMISSION:
+ unicast_negotiation_pre_send(tlv);
+ break;
case TLV_PATH_TRACE:
case TLV_ALTERNATE_TIME_OFFSET_INDICATOR:
case TLV_AUTHENTICATION:
diff --git a/tlv.h b/tlv.h
index 4ec9173..958555c 100644
--- a/tlv.h
+++ b/tlv.h
@@ -115,6 +115,34 @@ enum management_action {
#define TLV_NOT_SUPPORTED 0x0006
#define TLV_GENERAL_ERROR 0xFFFE
+#define CANCEL_UNICAST_MAINTAIN_REQUEST (1 << 0)
+#define CANCEL_UNICAST_MAINTAIN_GRANT (1 << 1)
+#define GRANT_UNICAST_RENEWAL_INVITED (1 << 0)
+
+struct ack_cancel_unicast_xmit_tlv {
+ Enumeration16 type;
+ UInteger16 length;
+ uint8_t message_type_flags;
+ uint8_t reserved;
+} PACKED;
+
+struct cancel_unicast_xmit_tlv {
+ Enumeration16 type;
+ UInteger16 length;
+ uint8_t message_type_flags;
+ uint8_t reserved;
+} PACKED;
+
+struct grant_unicast_xmit_tlv {
+ Enumeration16 type;
+ UInteger16 length;
+ uint8_t message_type;
+ Integer8 logInterMessagePeriod;
+ UInteger32 durationField;
+ uint8_t reserved;
+ uint8_t flags;
+} PACKED;
+
struct management_tlv {
Enumeration16 type;
UInteger16 length;
@@ -172,6 +200,14 @@ struct path_trace_tlv {
struct ClockIdentity cid[0];
} PACKED;
+struct request_unicast_xmit_tlv {
+ Enumeration16 type;
+ UInteger16 length;
+ uint8_t message_type;
+ Integer8 logInterMessagePeriod;
+ UInteger32 durationField;
+} PACKED;
+
static inline unsigned int path_length(struct path_trace_tlv *p)
{
return p->length / sizeof(struct ClockIdentity);
--
2.11.0
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Linuxptp-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel