OpENer - Open Source EtherNet/IP(TM) I/O Target Stack  2.1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cipepath.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright (c) 2009, Rockwell Automation, Inc.
3  * All rights reserved.
4  *
5  ******************************************************************************/
6 
7 #include <stdbool.h>
8 #include <stdlib.h>
9 
10 #include "cipepath.h"
11 
12 #include "endianconv.h"
13 #include "cipelectronickey.h"
14 #include "trace.h"
15 #include <assert.h>
16 
17 const unsigned int kPortSegmentExtendedPort = 15;
19 /* Segments */
20 #define SEGMENT_TYPE_PORT_SEGMENT 0x00
21 #define SEGMENT_TYPE_LOGICAL_SEGMENT 0x20
22 #define SEGMENT_TYPE_NETWORK_SEGMENT 0x40
23 #define SEGMENT_TYPE_SYMBOLIC_SEGMENT 0x60
24 #define SEGMENT_TYPE_DATA_SEGMENT 0x80
25 #define SEGMENT_TYPE_DATA_TYPE_CONSTRUCTED 0xA0
26 #define SEGMENT_TYPE_DATA_TYPE_ELEMENTARTY 0xC0
27 #define SEGMENT_TYPE_SEGMENT_RESERVED 0xE0
29 #define LOGICAL_SEGMENT_TYPE_CLASS_ID 0x00
30 #define LOGICAL_SEGMENT_TYPE_INSTANCE_ID 0x04
31 #define LOGICAL_SEGMENT_TYPE_MEMBER_ID 0x08
32 #define LOGICAL_SEGMENT_TYPE_CONNECTION_POINT 0x0C
33 #define LOGICAL_SEGMENT_TYPE_ATTRIBUTE_ID 0x10
34 #define LOGICAL_SEGMENT_TYPE_SPECIAL 0x14
35 #define LOGICAL_SEGMENT_TYPE_SERVICE_ID 0x18
36 #define LOGICAL_SEGMENT_TYPE_EXTENDED_LOGICAL 0x1C
38 #define LOGICAL_SEGMENT_FORMAT_EIGHT_BIT 0x00
39 #define LOGICAL_SEGMENT_FORMAT_SIXTEEN_BIT 0x01
40 #define LOGICAL_SEGMENT_FORMAT_THIRTY_TWO_BIT 0x02
41 
42 #define LOGICAL_SEGMENT_EXTENDED_TYPE_RESERVED 0x00
43 #define LOGICAL_SEGMENT_EXTENDED_TYPE_ARRAY_INDEX 0x01
44 #define LOGICAL_SEGMENT_EXTENDED_TYPE_INDIRECT_ARRAY_INDEX 0x02
45 #define LOGICAL_SEGMENT_EXTENDED_TYPE_BIT_INDEX 0x03
46 #define LOGICAL_SEGMENT_EXTENDED_TYPE_INDIRECT_BIT_INDEX 0x04
47 #define LOGICAL_SEGMENT_EXTENDED_TYPE_STRUCTURE_MEMBER_NUMBER 0x05
48 #define LOGICAL_SEGMENT_EXTENDED_TYPE_STRUCTURE_MEMBER_HANDLE 0x06
49 
50 #define LOGICAL_SEGMENT_SPECIAL_TYPE_FORMAT_ELECTRONIC_KEY 0x00
51 #define ELECTRONIC_KEY_SEGMENT_KEY_FORMAT_4 0x04
52 
53 #define NETWORK_SEGMENT_SCHEDULE 0x01
54 #define NETWORK_SEGMENT_FIXED_TAG 0x02
55 #define NETWORK_SEGMENT_PRODUCTION_INHIBIT_TIME_IN_MILLISECONDS 0x03
56 #define NETWORK_SEGMENT_SAFETY 0x04
57 #define NETWORK_SEGMENT_PRODUCTION_INHIBIT_TIME_IN_MICROSECONDS 0x10
58 #define NETWORK_SEGMENT_EXTENDED_NETWORK 0x1F
59 
60 #define SYMBOLIC_SEGMENT_FORMAT_EXTENDED_STRING 0x00
61 
62 #define SYMBOLIC_SEGMENT_EXTENDED_FORMAT_DOUBLE_CHAR 0x20
63 #define SYMBOLIC_SEGMENT_EXTENDED_FORMAT_TRIPLE_CHAR 0x40
64 #define SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC 0xC0
65 
66 #define SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC_USINT_TYPE 0x06
67 #define SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC_UINT_TYPE 0x07
68 #define SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC_UDINT_TYPE 0x08
69 
70 #define DATA_SEGMENT_SUBTYPE_SIMPLE_DATA 0x00
71 #define DATA_SEGMENT_SUBTYPE_ANSI_EXTENDED_SYMBOL 0x11
72 
73 
74 
75 /*** Path Segment ***/
76 SegmentType GetPathSegmentType(const CipOctet *const cip_path) {
77  const unsigned int kSegmentTypeMask = 0xE0;
78  const unsigned int segment_type = *cip_path & kSegmentTypeMask;
80  switch (segment_type) {
82  result = kSegmentTypePortSegment;
83  break;
86  break;
89  break;
92  break;
94  result = kSegmentTypeDataSegment;
95  break;
98  break;
101  break;
103  result = kSegmentTypeReserved;
104  break;
105  default:
107  "Invalid Segment type in the message! We should never come here!\n")
108  break;
109  }
110  return result;
111 }
112 
114  unsigned char *const cip_path) {
115  switch (segment_type) {
117  *cip_path = SEGMENT_TYPE_PORT_SEGMENT;
118  break;
120  *cip_path = SEGMENT_TYPE_LOGICAL_SEGMENT;
121  break;
123  *cip_path = SEGMENT_TYPE_NETWORK_SEGMENT;
124  break;
126  *cip_path = SEGMENT_TYPE_SYMBOLIC_SEGMENT;
127  break;
129  *cip_path = SEGMENT_TYPE_DATA_SEGMENT;
130  break;
133  break;
136  break;
138  *cip_path = SEGMENT_TYPE_SEGMENT_RESERVED;
139  break;
140  default:
142  "Invalid Segment type chosen! We should never come here!\n")
143  break;
144  }
145 }
146 
147 /*** Port Segment ***/
149  const unsigned char *const cip_path) {
150  const unsigned int kExtendedLinkAddressSizeMask = 0x10;
151  if ( kExtendedLinkAddressSizeMask ==
152  (*cip_path & kExtendedLinkAddressSizeMask) ) {
153  return true;
154  }
155  return false;
156 }
157 
159  const unsigned char *const cip_path) {
160  const unsigned int kPortIdentifierMask = 0x0F;
161  unsigned int port_identifier = *cip_path & kPortIdentifierMask;
162 /* OPENER_ASSERT(0 != port_identifier, "Use of reserved port identifier 0\n"); */
164  OPENER_ASSERT(0 != port_identifier)
165  return port_identifier;
166 }
167 
168 void SetPathPortSegmentPortIdentifier(const unsigned int port_identifier,
169  unsigned char *const cip_path) {
170 /* OPENER_ASSERT(
171  port_identifier < 16,
172  "Port identifier too large for standard port identifier field\n"); */
173  OPENER_ASSERT(port_identifier < 16)
174  (*cip_path) |= port_identifier;
175 }
176 
178  const unsigned char *const cip_path) {
179 /* OPENER_ASSERT(false == GetPathPortSegmentExtendedLinkAddressSizeBit(cip_path),
180  "Call to non existent extended link address size\n") */
181  OPENER_ASSERT( true ==
183  return *(cip_path + 1);
184 }
185 
187  const unsigned char *const cip_path) {
188 /* OPENER_ASSERT(kPortSegmentExtendedPort == GetPathPortSegmentPortIdentifier(cip_path),
189  "There is no extended port available!\n") */
192  const unsigned int kExtendedPortSegmentPosition =
193  GetPathPortSegmentExtendedLinkAddressSizeBit(cip_path) == true ? 2 : 1;
194  return cip_path[kExtendedPortSegmentPosition]
195  + (cip_path[kExtendedPortSegmentPosition + 1] << 8);
196 }
197 
199  const unsigned int extended_port_identifier,
200  CipOctet *const cip_path) {
202  const unsigned int kExtendedPortSegmentPosition =
203  GetPathPortSegmentExtendedLinkAddressSizeBit(cip_path) == true ? 2 : 1;
204  cip_path[kExtendedPortSegmentPosition] = (char) (extended_port_identifier
205  & 0x00FF);
206  cip_path[kExtendedPortSegmentPosition + 1] =
207  (char) ( (extended_port_identifier & 0xFF00) >> 8 );
208 }
209 /*** Port Segment ***/
210 
211 /*** Logical Segment ***/
212 
214  const unsigned char *const cip_path) {
216  const unsigned int kLogicalTypeMask = 0x1C;
217  const unsigned int logical_type = (*cip_path) & kLogicalTypeMask;
219  switch (logical_type) {
222  break;
225  break;
228  break;
231  break;
234  break;
237  break;
240  break;
243  break;
244  default:
246  "Logical segment/logical type: It is not possible to reach this point!\n")
247  break;
248  }
249  return result;
250 }
251 
253  CipOctet *const cip_path) {
255  switch (logical_type) {
257  (*cip_path) |= LOGICAL_SEGMENT_TYPE_CLASS_ID;
258  break;
260  (*cip_path) |= LOGICAL_SEGMENT_TYPE_INSTANCE_ID;
261  break;
263  (*cip_path) |= LOGICAL_SEGMENT_TYPE_MEMBER_ID;
264  break;
267  break;
269  (*cip_path) |= LOGICAL_SEGMENT_TYPE_ATTRIBUTE_ID;
270  break;
272  (*cip_path) |= LOGICAL_SEGMENT_TYPE_SPECIAL;
273  break;
275  (*cip_path) |= LOGICAL_SEGMENT_TYPE_SERVICE_ID;
276  break;
279  break;
280  default:
282  "Logical segment/logical type: It is not possible to reach this point!\n");
283  break;
284  }
285 }
286 
288  const unsigned char *const cip_path) {
290  const unsigned int kLogicalFormatMask = 0x03;
291  const unsigned int logical_format = (*cip_path) & kLogicalFormatMask;
293  switch (logical_format) {
296  break;
299  break;
302  break;
303  default:
305  "Logical segment/logical type: Invalid logical type detected!\n")
306  break;
307  }
308  return result;
309 }
310 
312  CipOctet *const cip_path) {
314  GetPathSegmentType( (const CipOctet *)cip_path ) )
315  switch (format) {
317  (*cip_path) |= LOGICAL_SEGMENT_FORMAT_EIGHT_BIT;
318  break;
320  (*cip_path) |= LOGICAL_SEGMENT_FORMAT_SIXTEEN_BIT;
321  break;
324  break;
325  default:
327  "Logical segment/logical type: Invalid logical type detected!\n")
328  break;
329  }
330 }
331 
332 const CipDword CipEpathGetLogicalValue(const EipUint8 **message) {
333  LogicalSegmentLogicalFormat logical_format =
335  CipDword data = 0;
336  MoveMessageNOctets(1, message); /* Move to logical value */
337  switch (logical_format) {
339  data = GetSintFromMessage(message);
340  break;
342  MoveMessageNOctets(1, message); /* Pad byte needs to be skipped */
343  data = GetIntFromMessage(message);
344  break;
346  MoveMessageNOctets(1, message); /* Pad byte needs to be skipped */
347  data = GetDintFromMessage(message);
348  break;
349  default:
350  OPENER_ASSERT(false) /* shall not happen! */
351  break;
352  }
353  return data;
354 }
355 
356 size_t CipEpathSetLogicalValue(const CipDword logical_value,
357  const LogicalSegmentLogicalFormat logical_format,
358  CipOctet **message) {
359  size_t written_bytes = 0;
360  switch(logical_value) {
362  written_bytes = AddSintToMessage(logical_value, message);
363  break;
365  written_bytes = MoveMessageNOctets(1, (const CipOctet **)message); /* Needed for padding */
366  written_bytes += AddIntToMessage(logical_value, message);
367  break;
369  written_bytes = MoveMessageNOctets(1,(const CipOctet **)message); /* Needed for padding */
370  written_bytes += AddDintToMessage(logical_value, message);
371  break;
372  default:
373  OPENER_ASSERT(false) /* This should never happen! */
374  written_bytes = 0;
375  }
376  return written_bytes;
377 }
378 
380  const unsigned char *const cip_path) {
381 /* OPENER_ASSERT(LOGICAL_SEGMENT_TYPE_EXTENDED_kLogicalSegmentLogicalTypeExtendedLogicalMessageValue == GetPathLogicalSegmentLogicalType(cip_path),
382  "Trying to extract non-existent extended logical type") */
384  cip_path) )
385  const unsigned int extended_logical_type = *(cip_path + 1);
388  switch(extended_logical_type) {
402  }
403  return result;
404 }
405 
407 GetPathLogicalSegmentSpecialTypeLogicalType(const unsigned char *const cip_path)
408 {
409 /* OPENER_ASSERT(kSegmentTypeLogicalSegment == GetPathSegmentType(cip_path), "Not a logical segment!\n") */
412  cip_path) )
413  const unsigned int kLogicalFormatMask = 0x03;
414  const unsigned int logical_format = (*cip_path) & kLogicalFormatMask;
415 
418  switch(logical_format) {
421  default: result = kLogicalSegmentSpecialTypeLogicalFormatReserved; break;
422  }
423  return result;
424 }
425 
427  const unsigned char *const cip_path) {
428 /* OPENER_ASSERT(kLogicalSegmentSpecialTypeLogicalFormatElectronicKey ==
429  GetPathLogicalSegmentSpecialTypeLogicalType(cip_path), "Not an electronic key!\n") */
433  switch( *(cip_path + 1) ) {
436  default: result = kElectronicKeySegmentFormatReserved; break;
437  }
438  return result;
439 }
440 
442  const CipOctet **const message,
443  ElectronicKeyFormat4 *key) {
446 
447  MoveMessageNOctets(2, message);
452  GetSintFromMessage(message) );
454 }
455 
456 /*** Logical Segment ***/
457 
458 
459 /*** Network Segment ***/
460 
467  const unsigned char *const cip_path) {
469  const unsigned int kSubtypeMask = 0x1F;
470  const unsigned int subtype = (*cip_path) & kSubtypeMask;
472  switch(subtype) {
480  result = kNetworkSegmentSubtypeSafetySegment; break;
485  default: result = kNetworkSegmentSubtypeReserved; break;
486  }
487 
488  return result;
489 }
490 
498  const unsigned char *const cip_path) {
499 /* OPENER_ASSERT(kSegmentTypeNetworkSegment == GetPathSegmentType(cip_path),"Not a network segment!\n")
500  OPENER_ASSERT(kNetworkSegmentSubtypeProductionInhibitTimeInMilliseconds == GetPathNetworkSegmentSubtype(cip_path),
501  "Not a Production Inhibit Time milliseconds segment!\n") */
504  cip_path) )
505  return *(cip_path + 1);
506 }
507 
515  const unsigned char *const cip_path) {
516 /* OPENER_ASSERT(kSegmentTypeNetworkSegment == GetPathSegmentType(cip_path),"Not a network segment!\n")
517  OPENER_ASSERT(kNetworkSegmentSubtypeProductionInhibitTimeInMicroseconds == GetPathNetworkSegmentSubtype(cip_path),
518  "Not a Production Inhibit Time microseconds segment!\n")
519  OPENER_ASSERT(2 == *(cip_path + 1), "Data Words length is incorrect! See CIP Spec Vol.1 C-1.4.3.3.2\n") */
520 
523  cip_path) )
524  OPENER_ASSERT( 2 == *(cip_path + 1) )
525 
526  const unsigned char *message_runner = cip_path + 2;
527  return GetDintFromMessage(&message_runner);
528 }
529 
530 /*** Network Segment ***/
531 
532 /*** Symbolic Segment ***/
533 
535  const unsigned char *const cip_path) {
536  const unsigned int kSymbolicSegmentFormatMask = 0x1F;
538  (*cip_path & kSymbolicSegmentFormatMask) ) {
540  }
542 }
543 
545  const unsigned char *const cip_path) {
546  const unsigned int kSymbolicSegmentASCIIFormatLength = 0x1F;
547  const unsigned int length = *cip_path & kSymbolicSegmentASCIIFormatLength;
548  OPENER_ASSERT(0 != length)
549  return length;
550 }
551 
553  const unsigned char *const cip_path) {
554  const unsigned int kSymbolicSegmentExtendedFormatNumericTypeMask = 0x1F;
555  const unsigned int numeric_subtype = *(cip_path + 1) &
556  kSymbolicSegmentExtendedFormatNumericTypeMask;
558  switch(numeric_subtype) {
565  default: result = kSymbolicSegmentExtendedFormatReserved; break;
566  }
567  return result;
568 }
569 
571  const unsigned char *const cip_path) {
574  cip_path) )
575  const unsigned int kSymbolicSegmentExtendedFormatMask = 0xE0;
576  const unsigned int extended_type = *(cip_path + 1) &
577  kSymbolicSegmentExtendedFormatMask;
579  switch(extended_type) {
585  GetPathSymbolicSegmentNumericType(cip_path); break;
586  default: result = kSymbolicSegmentExtendedFormatReserved; break;
587  }
588  return result;
589 }
590 
591 /*** Symbolic Segment ***/
592 
593 /*** Data Segment ***/
594 
595 DataSegmentSubtype GetPathDataSegmentSubtype(const unsigned char *const cip_path)
596 {
597  const unsigned int kDataSegmentSubtypeMask = 0x1F;
598  const unsigned int data_subtype = (*cip_path) & kDataSegmentSubtypeMask;
599 
601  switch(data_subtype) {
603  result = kDataSegmentSubtypeSimpleData; break;
606  default: result = kDataSegmentSubtypeReserved; break;
607  }
608  return result;
609 }
610 
617  const unsigned char *const cip_path) {
618 /* OPENER_ASSERT(kSegmentTypeDataSegment == GetPathSegmentType(cip_path),"Not a data segment!\n");
619  OPENER_ASSERT(kDataSegmentSubtypeSimpleData == GetPathDataSegmentSubtype(cip_path), "Not a simple data segment!\n") */
622  GetPathDataSegmentSubtype(cip_path) )
623 
624  const unsigned char *message_runner = cip_path + 1;
625  return GetSintFromMessage(&message_runner);
626 }
627 
628 /*** End Data Segment ***/
629 
630 /* Special purpose functions */
631 
633  CipDword value) {
634  LogicalSegmentLogicalFormat logical_format =
636  if(0xFF < value) {
638  }
639  if(0xFFFF < value) {
641  }
642  return logical_format;
643 }
644 
646  const CipConnectionPathEpath *const connection_epath,
647  CipOctet **encoded_path) {
648 
649  size_t encoded_path_length = 0;
650  {
653  *encoded_path);
654  LogicalSegmentLogicalFormat logical_value =
656  SetPathLogicalSegmentLogicalFormat(logical_value, *encoded_path);
657  encoded_path_length += 1;
658  MoveMessageNOctets(1, (const CipOctet **)encoded_path);
659  encoded_path_length += CipEpathSetLogicalValue(connection_epath->class_id,
660  logical_value,
661  encoded_path);
662  }
663 
664  {
667  *encoded_path);
668  LogicalSegmentLogicalFormat logical_value =
670  SetPathLogicalSegmentLogicalFormat(logical_value, *encoded_path);
671  encoded_path_length += 1;
672  MoveMessageNOctets(1, (const CipOctet **)encoded_path);
673  encoded_path_length += CipEpathSetLogicalValue(
674  connection_epath->instance_id,
675  logical_value,
676  encoded_path);
677  }
678 
679  if(0 != connection_epath->attribute_id_or_connection_point) {
682  *encoded_path);
683  LogicalSegmentLogicalFormat logical_value =
685  connection_epath->attribute_id_or_connection_point);
686  SetPathLogicalSegmentLogicalFormat(logical_value, *encoded_path);
687  encoded_path_length += 1;
688  MoveMessageNOctets(1, (const CipOctet **)encoded_path);
689  encoded_path_length += CipEpathSetLogicalValue(
690  connection_epath->attribute_id_or_connection_point,
691  logical_value,
692  encoded_path);
693  }
694  return encoded_path_length += 1;
695 }
696 
697 bool CipEpathEqual(const CipOctet *const path1,
698  const CipUint path1_length,
699  const CipOctet *const path2,
700  const CipUint path2_length) {
701  if(path1_length != path2_length) {
702  return false;
703  }
704  for(size_t i = 0; i < path1_length; ++i) {
705  if(path1[i] != path2[i]) {
706  return false;
707  }
708  }
709  return true;
710 }
711 
#define NETWORK_SEGMENT_PRODUCTION_INHIBIT_TIME_IN_MICROSECONDS
Definition: cipepath.c:57
LogicalSegmentLogicalFormat GetPathLogicalSegmentLogicalFormat(const unsigned char *const cip_path)
Gets the Logical Format of a Logical Segment EPath message.
Definition: cipepath.c:287
unsigned int GetPathPortSegmentPortIdentifier(const unsigned char *const cip_path)
Only to be used on Port Segments. Returns the Port Identifier.
Definition: cipepath.c:158
#define SEGMENT_TYPE_DATA_TYPE_ELEMENTARTY
Definition: cipepath.c:26
#define NETWORK_SEGMENT_FIXED_TAG
Definition: cipepath.c:54
Tracing infrastructure for OpENer.
void SetPathPortSegmentExtendedPortIdentifier(const unsigned int extended_port_identifier, CipOctet *const cip_path)
Sets the Extended Port Identifier in a EPath Port Segment message.
Definition: cipepath.c:198
#define LOGICAL_SEGMENT_TYPE_INSTANCE_ID
Definition: cipepath.c:30
#define LOGICAL_SEGMENT_TYPE_CONNECTION_POINT
Definition: cipepath.c:32
CipUsint GetPathDataSegmentSimpleDataWordLength(const unsigned char *const cip_path)
Returns the amount of 16-bit data words in the Simple Data EPath.
Definition: cipepath.c:616
void SetPathLogicalSegmentLogicalFormat(LogicalSegmentLogicalFormat format, CipOctet *const cip_path)
Definition: cipepath.c:311
#define NETWORK_SEGMENT_SCHEDULE
Definition: cipepath.c:53
#define LOGICAL_SEGMENT_FORMAT_THIRTY_TWO_BIT
Definition: cipepath.c:40
#define DATA_SEGMENT_SUBTYPE_SIMPLE_DATA
Definition: cipepath.c:70
void SetPathLogicalSegmentLogicalType(LogicalSegmentLogicalType logical_type, CipOctet *const cip_path)
Definition: cipepath.c:252
unsigned int GetPathPortSegmentExtendedPortNumber(const unsigned char *const cip_path)
Only to be used on Port Segments with Extended Port Number. Gets the Extended Port Number...
Definition: cipepath.c:186
#define OPENER_ASSERT(assertion)
#define SEGMENT_TYPE_DATA_SEGMENT
Definition: cipepath.c:24
#define LOGICAL_SEGMENT_EXTENDED_TYPE_INDIRECT_ARRAY_INDEX
Definition: cipepath.c:44
void ElectronicKeyFormat4SetVendorId(ElectronicKeyFormat4 *const electronic_key, const CipUint vendor_id)
Sets vendor ID in the electronic key.
EipUint32 GetDintFromMessage(const EipUint8 **const buffer)
Reads EIP_UINT32 from *buffer and converts little endian to host.
Definition: endianconv.c:83
CipDword instance_id
Definition: cipepath.h:165
CipDword attribute_id_or_connection_point
Definition: cipepath.h:166
Responsible for Endianess conversion.
EipUint8 GetSintFromMessage(const EipUint8 **const buffer)
Reads EIP_UINT8 from *buffer and converts little endian to host.
Definition: endianconv.c:29
#define SYMBOLIC_SEGMENT_EXTENDED_FORMAT_DOUBLE_CHAR
Definition: cipepath.c:62
SymbolicSegmentExtendedFormat GetPathSymbolicSegmentExtendedFormat(const unsigned char *const cip_path)
Gets the Extended Format subtype of a Symbolic Segment EPath message.
Definition: cipepath.c:570
#define SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC
Definition: cipepath.c:64
enum data_segment_subtype DataSegmentSubtype
Data segment sub types.
#define SEGMENT_TYPE_LOGICAL_SEGMENT
Definition: cipepath.c:21
void ElectronicKeyFormat4SetDeviceType(ElectronicKeyFormat4 *const electronic_key, const CipUint device_type)
Sets the device type in the electronic key.
#define SEGMENT_TYPE_NETWORK_SEGMENT
Definition: cipepath.c:22
enum logical_segment_extended_logical_type LogicalSegmentExtendedLogicalType
SymbolicSegmentFormat GetPathSymbolicSegmentFormat(const unsigned char *const cip_path)
Gets the Symbolic Segment Format of the Symbolic Segment EPath message.
Definition: cipepath.c:534
#define LOGICAL_SEGMENT_SPECIAL_TYPE_FORMAT_ELECTRONIC_KEY
Definition: cipepath.c:50
#define LOGICAL_SEGMENT_EXTENDED_TYPE_BIT_INDEX
Definition: cipepath.c:45
DataSegmentSubtype GetPathDataSegmentSubtype(const unsigned char *const cip_path)
Gets the Data Segment subtype of a Data Segment EPath message.
Definition: cipepath.c:595
#define SEGMENT_TYPE_SEGMENT_RESERVED
Definition: cipepath.c:27
#define LOGICAL_SEGMENT_EXTENDED_TYPE_STRUCTURE_MEMBER_NUMBER
Definition: cipepath.c:47
#define LOGICAL_SEGMENT_EXTENDED_TYPE_ARRAY_INDEX
Definition: cipepath.c:43
bool CipEpathEqual(const CipOctet *const path1, const CipUint path1_length, const CipOctet *const path2, const CipUint path2_length)
Definition: cipepath.c:697
uint8_t CipOctet
Data types as defined in the CIP Specification Vol 1 Appendix C.
Definition: typedefs.h:41
LogicalSegmentSpecialTypeLogicalFormat GetPathLogicalSegmentSpecialTypeLogicalType(const unsigned char *const cip_path)
Gets the Special Type Logical Type of a Logical Segment EPath message.
Definition: cipepath.c:407
#define LOGICAL_SEGMENT_TYPE_SERVICE_ID
Definition: cipepath.c:35
#define LOGICAL_SEGMENT_TYPE_CLASS_ID
Definition: cipepath.c:29
ElectronicKeySegmentFormat GetPathLogicalSegmentElectronicKeyFormat(const unsigned char *const cip_path)
Gets the Electronic Key format of a Logical Segment Special Type EPath message.
Definition: cipepath.c:426
int AddIntToMessage(const EipUint16 data, EipUint8 **const buffer)
converts UINT16 data from host to little endian an writes it to buffer.
Definition: endianconv.c:117
unsigned int GetPathPortSegmentLinkAddressSize(const unsigned char *const cip_path)
Only to be used on Port Segments. Gets the Link Address Size.
Definition: cipepath.c:177
#define LOGICAL_SEGMENT_FORMAT_SIXTEEN_BIT
Definition: cipepath.c:39
uint8_t EipUint8
Definition: typedefs.h:32
enum network_segment_subtype NetworkSegmentSubtype
All types of network segment types for the use in all code.
int AddDintToMessage(const EipUint32 data, EipUint8 **const buffer)
Converts UINT32 data from host to little endian and writes it to buffer.
Definition: endianconv.c:132
#define SEGMENT_TYPE_SYMBOLIC_SEGMENT
Definition: cipepath.c:23
#define LOGICAL_SEGMENT_EXTENDED_TYPE_INDIRECT_BIT_INDEX
Definition: cipepath.c:46
enum logical_segment_logical_format LogicalSegmentLogicalFormat
Enum containing values how long the encoded value will be (8, 16, or 32 bit)
void SetPathSegmentType(SegmentType segment_type, unsigned char *const cip_path)
Sets the basic segment type of an CIP EPath to be sent.
Definition: cipepath.c:113
enum segment_type SegmentType
Segment type Enum.
#define SEGMENT_TYPE_PORT_SEGMENT
Definition: cipepath.c:20
int AddSintToMessage(const EipUint8 data, EipUint8 **const buffer)
converts UINT8 data from host to little endian an writes it to buffer.
Definition: endianconv.c:103
void ElectronicKeyFormat4SetMajorRevisionCompatibility(ElectronicKeyFormat4 *const electronic_key, const CipByte major_revision_compatibility)
Sets the major revision byte including the compatibility flag.
int MoveMessageNOctets(const int amount_of_bytes_moved, const CipOctet **message_runner)
Definition: endianconv.c:258
size_t CipEpathSetLogicalValue(const CipDword logical_value, const LogicalSegmentLogicalFormat logical_format, CipOctet **message)
Definition: cipepath.c:356
#define DATA_SEGMENT_SUBTYPE_ANSI_EXTENDED_SYMBOL
Definition: cipepath.c:71
LogicalSegmentLogicalFormat CipEpathGetNeededLogicalFormatForValue(CipDword value)
Definition: cipepath.c:632
#define SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC_UDINT_TYPE
Definition: cipepath.c:68
NetworkSegmentSubtype GetPathNetworkSegmentSubtype(const unsigned char *const cip_path)
Return the Network Segment subtype.
Definition: cipepath.c:466
#define LOGICAL_SEGMENT_TYPE_ATTRIBUTE_ID
Definition: cipepath.c:33
uint8_t CipUsint
Definition: typedefs.h:46
LogicalSegmentExtendedLogicalType GetPathLogicalSegmentExtendedLogicalType(const unsigned char *const cip_path)
Gets the Extended Logical Type of a Logical Segment EPath message.
Definition: cipepath.c:379
#define SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC_USINT_TYPE
Definition: cipepath.c:66
#define LOGICAL_SEGMENT_TYPE_SPECIAL
Definition: cipepath.c:34
#define LOGICAL_SEGMENT_EXTENDED_TYPE_STRUCTURE_MEMBER_HANDLE
Definition: cipepath.c:48
LogicalSegmentLogicalType GetPathLogicalSegmentLogicalType(const unsigned char *const cip_path)
Gets the Logical Type of an EPath Logical Segment message.
Definition: cipepath.c:213
enum symbolic_segment_format SymbolicSegmentFormat
Symbolic segment formats.
enum electronic_key_segment_format ElectronicKeySegmentFormat
Electronic key formats.
const unsigned int kPortSegmentExtendedPort
Definition: cipepath.c:17
#define NETWORK_SEGMENT_SAFETY
Definition: cipepath.c:56
CipUdint GetPathNetworkSegmentProductionInhibitTimeInMicroseconds(const unsigned char *const cip_path)
Return the Production Inhibit Time in microseconds from an EPath.
Definition: cipepath.c:514
#define NETWORK_SEGMENT_EXTENDED_NETWORK
Definition: cipepath.c:58
SymbolicSegmentExtendedFormat GetPathSymbolicSegmentNumericType(const unsigned char *const cip_path)
Gets the Numeric subtype of a Symbolic Segment Extended Format EPath message.
Definition: cipepath.c:552
#define SYMBOLIC_SEGMENT_EXTENDED_FORMAT_TRIPLE_CHAR
Definition: cipepath.c:63
#define LOGICAL_SEGMENT_TYPE_EXTENDED_LOGICAL
Definition: cipepath.c:36
void ElectronicKeyFormat4SetMinorRevision(ElectronicKeyFormat4 *const electronic_key, const CipUsint minor_revision)
Sets the devices minor revision in an format 4 electronic key.
#define SEGMENT_TYPE_DATA_TYPE_CONSTRUCTED
Definition: cipepath.c:25
const CipDword CipEpathGetLogicalValue(const EipUint8 **message)
Definition: cipepath.c:332
#define SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC_UINT_TYPE
Definition: cipepath.c:67
uint32_t CipUdint
Definition: typedefs.h:48
uint16_t CipUint
Definition: typedefs.h:47
#define SYMBOLIC_SEGMENT_FORMAT_EXTENDED_STRING
Definition: cipepath.c:60
EipUint16 GetIntFromMessage(const EipUint8 **const buffer)
Reads EIP_UINT16 from *buffer and converts little endian to host.
Definition: endianconv.c:57
#define ELECTRONIC_KEY_SEGMENT_KEY_FORMAT_4
Definition: cipepath.c:51
void GetElectronicKeyFormat4FromMessage(const CipOctet **const message, ElectronicKeyFormat4 *key)
Gets the data for an Electronic Key of format 4 from the EPath message.
Definition: cipepath.c:441
size_t CipEpathEncodeConnectionEpath(const CipConnectionPathEpath *const connection_epath, CipOctet **encoded_path)
Definition: cipepath.c:645
CipUsint GetPathNetworkSegmentProductionInhibitTimeInMilliseconds(const unsigned char *const cip_path)
Return the Production Inhibit Time in milliseconds from an EPath.
Definition: cipepath.c:497
segment_type
Segment type Enum.
Definition: cipepath.h:59
uint32_t CipDword
Definition: typedefs.h:45
unsigned int GetPathSymbolicSegmentASCIIFormatLength(const unsigned char *const cip_path)
Definition: cipepath.c:544
enum symbolic_segment_extended_format SymbolicSegmentExtendedFormat
Extended symbolic symbol formats.
void SetPathPortSegmentPortIdentifier(const unsigned int port_identifier, unsigned char *const cip_path)
Sets the Port Identifier form an Port Segment EPath to be sent.
Definition: cipepath.c:168
bool GetPathPortSegmentExtendedLinkAddressSizeBit(const unsigned char *const cip_path)
Only to be used on Port Segments. Returns if the Port Segment has the extended link address size bit ...
Definition: cipepath.c:148
SegmentType GetPathSegmentType(const CipOctet *const cip_path)
Gets the basic segment type of a CIP EPath.
Definition: cipepath.c:76
enum logical_segment_type LogicalSegmentLogicalType
Enum containing values which kind of logical segment is encoded.
#define LOGICAL_SEGMENT_TYPE_MEMBER_ID
Definition: cipepath.c:31
#define LOGICAL_SEGMENT_FORMAT_EIGHT_BIT
Definition: cipepath.c:38
void ElectronicKeyFormat4SetProductCode(ElectronicKeyFormat4 *const electronic_key, const CipUint product_code)
Set product code in the electronic key.
#define NETWORK_SEGMENT_PRODUCTION_INHIBIT_TIME_IN_MILLISECONDS
Definition: cipepath.c:55
enum logical_segment_special_type_logical_format LogicalSegmentSpecialTypeLogicalFormat