| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692 |
- /*******************************************************************************
- * Copyright (c) 2009, Rockwell Automation, Inc.
- * All rights reserved.
- *
- ******************************************************************************/
- #include <stdbool.h>
- #include <stdlib.h>
- #include "cipepath.h"
- #include "endianconv.h"
- #include "cipelectronickey.h"
- #include "trace.h"
- #include <assert.h>
- const unsigned int kPortSegmentExtendedPort = 15; /**< Reserved port segment port value, indicating the use of the extended port field */
- /*** Path Segment ***/
- SegmentType GetPathSegmentType(const CipOctet *const cip_path) {
- const unsigned int kSegmentTypeMask = 0xE0;
- const unsigned int segment_type = *cip_path & kSegmentTypeMask;
- SegmentType result = kSegmentTypeReserved;
- switch(segment_type) {
- case SEGMENT_TYPE_PORT_SEGMENT:
- result = kSegmentTypePortSegment;
- break;
- case SEGMENT_TYPE_LOGICAL_SEGMENT:
- result = kSegmentTypeLogicalSegment;
- break;
- case SEGMENT_TYPE_NETWORK_SEGMENT:
- result = kSegmentTypeNetworkSegment;
- break;
- case SEGMENT_TYPE_SYMBOLIC_SEGMENT:
- result = kSegmentTypeSymbolicSegment;
- break;
- case SEGMENT_TYPE_DATA_SEGMENT:
- result = kSegmentTypeDataSegment;
- break;
- case SEGMENT_TYPE_DATA_TYPE_CONSTRUCTED:
- result = kSegmentTypeDataTypeConstructed;
- break;
- case SEGMENT_TYPE_DATA_TYPE_ELEMENTARTY:
- result = kSegmentTypeDataTypeElementary;
- break;
- case SEGMENT_TYPE_SEGMENT_RESERVED:
- result = kSegmentTypeReserved;
- break;
- default:
- OPENER_TRACE_ERR(
- "Invalid Segment type in the message! We should never come here!\n");
- OPENER_ASSERT(false);
- break;
- }
- return result;
- }
- void SetPathSegmentType(SegmentType segment_type,
- unsigned char *const cip_path) {
- switch(segment_type) {
- case kSegmentTypePortSegment:
- *cip_path = SEGMENT_TYPE_PORT_SEGMENT;
- break;
- case kSegmentTypeLogicalSegment:
- *cip_path = SEGMENT_TYPE_LOGICAL_SEGMENT;
- break;
- case kSegmentTypeNetworkSegment:
- *cip_path = SEGMENT_TYPE_NETWORK_SEGMENT;
- break;
- case kSegmentTypeSymbolicSegment:
- *cip_path = SEGMENT_TYPE_SYMBOLIC_SEGMENT;
- break;
- case kSegmentTypeDataSegment:
- *cip_path = SEGMENT_TYPE_DATA_SEGMENT;
- break;
- case kSegmentTypeDataTypeConstructed:
- *cip_path = SEGMENT_TYPE_DATA_TYPE_CONSTRUCTED;
- break;
- case kSegmentTypeDataTypeElementary:
- *cip_path = SEGMENT_TYPE_DATA_TYPE_ELEMENTARTY;
- break;
- case kSegmentTypeReserved:
- *cip_path = SEGMENT_TYPE_SEGMENT_RESERVED;
- break;
- default:
- OPENER_TRACE_ERR(
- "Invalid Segment type chosen! We should never come here!\n");
- OPENER_ASSERT(false);
- break;
- }
- }
- /*** Port Segment ***/
- bool GetPathPortSegmentExtendedLinkAddressSizeBit(
- const unsigned char *const cip_path) {
- const unsigned int kExtendedLinkAddressSizeMask = 0x10;
- if(kExtendedLinkAddressSizeMask ==
- (*cip_path & kExtendedLinkAddressSizeMask) ) {
- return true;
- }
- return false;
- }
- unsigned int GetPathPortSegmentPortIdentifier(
- const unsigned char *const cip_path) {
- const unsigned int kPortIdentifierMask = 0x0F;
- unsigned int port_identifier = *cip_path & kPortIdentifierMask;
- OPENER_ASSERT(kSegmentTypePortSegment == GetPathSegmentType(cip_path) );
- /* Use of reserved port identifier 0 */
- OPENER_ASSERT(0 != port_identifier);
- return port_identifier;
- }
- void SetPathPortSegmentPortIdentifier(const unsigned int port_identifier,
- unsigned char *const cip_path) {
- /* OPENER_ASSERT(
- port_identifier < 16,
- "Port identifier too large for standard port identifier field\n"); */
- OPENER_ASSERT(port_identifier < 16);
- (*cip_path) |= port_identifier;
- }
- unsigned int GetPathPortSegmentLinkAddressSize(
- const unsigned char *const cip_path) {
- /* OPENER_ASSERT(false == GetPathPortSegmentExtendedLinkAddressSizeBit(cip_path),
- "Call to non existent extended link address size\n"); */
- OPENER_ASSERT(true ==
- GetPathPortSegmentExtendedLinkAddressSizeBit(cip_path) );
- return *(cip_path + 1);
- }
- unsigned int GetPathPortSegmentExtendedPortNumber(
- const unsigned char *const cip_path) {
- /* OPENER_ASSERT(kPortSegmentExtendedPort == GetPathPortSegmentPortIdentifier(cip_path),
- "There is no extended port available!\n");*/
- OPENER_ASSERT(kPortSegmentExtendedPort ==
- GetPathPortSegmentPortIdentifier(cip_path) );
- const unsigned int kExtendedPortSegmentPosition =
- GetPathPortSegmentExtendedLinkAddressSizeBit(cip_path) == true ? 2 : 1;
- return cip_path[kExtendedPortSegmentPosition] +
- (cip_path[kExtendedPortSegmentPosition + 1] << 8);
- }
- void SetPathPortSegmentExtendedPortIdentifier(
- const unsigned int extended_port_identifier,
- CipOctet *const cip_path) {
- SetPathPortSegmentPortIdentifier(kPortSegmentExtendedPort, cip_path);
- const unsigned int kExtendedPortSegmentPosition =
- GetPathPortSegmentExtendedLinkAddressSizeBit(cip_path) == true ? 2 : 1;
- cip_path[kExtendedPortSegmentPosition] =
- (char) (extended_port_identifier & 0x00FF);
- cip_path[kExtendedPortSegmentPosition +
- 1] = (char) ( (extended_port_identifier & 0xFF00) >> 8 );
- }
- /*** Port Segment ***/
- /*** Logical Segment ***/
- LogicalSegmentLogicalType GetPathLogicalSegmentLogicalType(
- const unsigned char *const cip_path) {
- OPENER_ASSERT(kSegmentTypeLogicalSegment == GetPathSegmentType(cip_path) );
- const unsigned int kLogicalTypeMask = 0x1C;
- const unsigned int logical_type = (*cip_path) & kLogicalTypeMask;
- LogicalSegmentLogicalType result = kLogicalSegmentLogicalTypeExtendedLogical;
- switch(logical_type) {
- case LOGICAL_SEGMENT_TYPE_CLASS_ID:
- result = kLogicalSegmentLogicalTypeClassId;
- break;
- case LOGICAL_SEGMENT_TYPE_INSTANCE_ID:
- result = kLogicalSegmentLogicalTypeInstanceId;
- break;
- case LOGICAL_SEGMENT_TYPE_MEMBER_ID:
- result = kLogicalSegmentLogicalTypeMemberId;
- break;
- case LOGICAL_SEGMENT_TYPE_CONNECTION_POINT:
- result = kLogicalSegmentLogicalTypeConnectionPoint;
- break;
- case LOGICAL_SEGMENT_TYPE_ATTRIBUTE_ID:
- result = kLogicalSegmentLogicalTypeAttributeId;
- break;
- case LOGICAL_SEGMENT_TYPE_SPECIAL:
- result = kLogicalSegmentLogicalTypeSpecial;
- break;
- case LOGICAL_SEGMENT_TYPE_SERVICE_ID:
- result = kLogicalSegmentLogicalTypeServiceId;
- break;
- case LOGICAL_SEGMENT_TYPE_EXTENDED_LOGICAL:
- result = kLogicalSegmentLogicalTypeExtendedLogical;
- break;
- default:
- OPENER_TRACE_ERR(
- "Logical segment/logical type: It is not possible to reach this point!\n");
- OPENER_ASSERT(false);
- break;
- }
- return result;
- }
- void SetPathLogicalSegmentLogicalType(LogicalSegmentLogicalType logical_type,
- CipOctet *const cip_path) {
- OPENER_ASSERT(kSegmentTypeLogicalSegment == GetPathSegmentType(cip_path) );
- switch(logical_type) {
- case kLogicalSegmentLogicalTypeClassId:
- (*cip_path) |= LOGICAL_SEGMENT_TYPE_CLASS_ID;
- break;
- case kLogicalSegmentLogicalTypeInstanceId:
- (*cip_path) |= LOGICAL_SEGMENT_TYPE_INSTANCE_ID;
- break;
- case kLogicalSegmentLogicalTypeMemberId:
- (*cip_path) |= LOGICAL_SEGMENT_TYPE_MEMBER_ID;
- break;
- case kLogicalSegmentLogicalTypeConnectionPoint:
- (*cip_path) |= LOGICAL_SEGMENT_TYPE_CONNECTION_POINT;
- break;
- case kLogicalSegmentLogicalTypeAttributeId:
- (*cip_path) |= LOGICAL_SEGMENT_TYPE_ATTRIBUTE_ID;
- break;
- case kLogicalSegmentLogicalTypeSpecial:
- (*cip_path) |= LOGICAL_SEGMENT_TYPE_SPECIAL;
- break;
- case kLogicalSegmentLogicalTypeServiceId:
- (*cip_path) |= LOGICAL_SEGMENT_TYPE_SERVICE_ID;
- break;
- case kLogicalSegmentLogicalTypeExtendedLogical:
- (*cip_path) |= LOGICAL_SEGMENT_TYPE_EXTENDED_LOGICAL;
- break;
- default:
- OPENER_TRACE_ERR(
- "Logical segment/logical type: It is not possible to reach this point!\n");
- OPENER_ASSERT(false);
- break;
- }
- }
- LogicalSegmentLogicalFormat GetPathLogicalSegmentLogicalFormat(
- const unsigned char *const cip_path) {
- OPENER_ASSERT(kSegmentTypeLogicalSegment == GetPathSegmentType(cip_path) );
- const unsigned int kLogicalFormatMask = 0x03;
- const unsigned int logical_format = (*cip_path) & kLogicalFormatMask;
- LogicalSegmentLogicalFormat result = kLogicalSegmentLogicalFormatEightBit;
- switch(logical_format) {
- case LOGICAL_SEGMENT_FORMAT_EIGHT_BIT:
- result = kLogicalSegmentLogicalFormatEightBit;
- break;
- case LOGICAL_SEGMENT_FORMAT_SIXTEEN_BIT:
- result = kLogicalSegmentLogicalFormatSixteenBit;
- break;
- case LOGICAL_SEGMENT_FORMAT_THIRTY_TWO_BIT:
- result = kLogicalSegmentLogicalFormatThirtyTwoBit;
- break;
- default:
- OPENER_TRACE_ERR(
- "Logical segment/logical type: Invalid logical type detected!\n");
- OPENER_ASSERT(false);
- break;
- }
- return result;
- }
- void SetPathLogicalSegmentLogicalFormat(LogicalSegmentLogicalFormat format,
- CipOctet *const cip_path) {
- OPENER_ASSERT(kSegmentTypeLogicalSegment ==
- GetPathSegmentType( (const CipOctet * )cip_path ) );
- switch(format) {
- case kLogicalSegmentLogicalFormatEightBit:
- (*cip_path) |= LOGICAL_SEGMENT_FORMAT_EIGHT_BIT;
- break;
- case kLogicalSegmentLogicalFormatSixteenBit:
- (*cip_path) |= LOGICAL_SEGMENT_FORMAT_SIXTEEN_BIT;
- break;
- case kLogicalSegmentLogicalFormatThirtyTwoBit:
- (*cip_path) |= LOGICAL_SEGMENT_FORMAT_THIRTY_TWO_BIT;
- break;
- default:
- OPENER_TRACE_ERR(
- "Logical segment/logical type: Invalid logical type detected!\n");
- OPENER_ASSERT(false);
- break;
- }
- }
- CipDword CipEpathGetLogicalValue(const EipUint8 **message) {
- LogicalSegmentLogicalFormat logical_format =
- GetPathLogicalSegmentLogicalFormat(*message);
- CipDword data = 0;
- (*message) += 1; /* Move to logical value */
- switch(logical_format) {
- case kLogicalSegmentLogicalFormatEightBit:
- data = GetByteFromMessage(message);
- break;
- case kLogicalSegmentLogicalFormatSixteenBit:
- (*message) += 1; /* Pad byte needs to be skipped */
- data = GetWordFromMessage(message);
- break;
- case kLogicalSegmentLogicalFormatThirtyTwoBit:
- (*message) += 1; /* Pad byte needs to be skipped */
- data = GetDwordFromMessage(message);
- break;
- default:
- OPENER_ASSERT(false);/* shall not happen! */
- break;
- }
- return data;
- }
- void CipEpathSetLogicalValue(const CipDword logical_value,
- const LogicalSegmentLogicalFormat logical_format,
- CipMessageRouterResponse *const message) {
- switch(logical_format) {
- case kLogicalSegmentLogicalFormatEightBit:
- AddSintToMessage(logical_value, &message->message);
- break;
- case kLogicalSegmentLogicalFormatSixteenBit:
- MoveMessageNOctets(1, &message->message); /* Needed for padding */
- AddIntToMessage(logical_value, &message->message);
- break;
- case kLogicalSegmentLogicalFormatThirtyTwoBit:
- MoveMessageNOctets(1, &message->message); /* Needed for padding */
- AddDintToMessage(logical_value, &message->message);
- break;
- default:
- OPENER_ASSERT(false); /* This should never happen! */
- break;
- }
- }
- LogicalSegmentExtendedLogicalType GetPathLogicalSegmentExtendedLogicalType(
- const unsigned char *const cip_path) {
- /* OPENER_ASSERT(LOGICAL_SEGMENT_TYPE_EXTENDED_kLogicalSegmentLogicalTypeExtendedLogicalMessageValue == GetPathLogicalSegmentLogicalType(cip_path),
- "Trying to extract non-existent extended logical type") */
- OPENER_ASSERT(kLogicalSegmentLogicalTypeExtendedLogical == GetPathLogicalSegmentLogicalType(
- cip_path) );
- const unsigned int extended_logical_type = *(cip_path + 1);
- LogicalSegmentExtendedLogicalType result =
- kLogicalSegmentExtendedLogicalTypeReserved;
- switch(extended_logical_type) {
- case LOGICAL_SEGMENT_EXTENDED_TYPE_ARRAY_INDEX:
- result = kLogicalSegmentExtendedLogicalTypeArrayIndex;
- break;
- case LOGICAL_SEGMENT_EXTENDED_TYPE_INDIRECT_ARRAY_INDEX:
- result = kLogicalSegmentExtendedLogicalTypeIndirectArrayIndex;
- break;
- case LOGICAL_SEGMENT_EXTENDED_TYPE_BIT_INDEX:
- result = kLogicalSegmentExtendedLogicalTypeBitIndex;
- break;
- case LOGICAL_SEGMENT_EXTENDED_TYPE_INDIRECT_BIT_INDEX:
- result = kLogicalSegmentExtendedLogicalTypeIndirectBitIndex;
- break;
- case LOGICAL_SEGMENT_EXTENDED_TYPE_STRUCTURE_MEMBER_NUMBER:
- result = kLogicalSegmentExtendedLogicalTypeStructureMemberNumber;
- break;
- case LOGICAL_SEGMENT_EXTENDED_TYPE_STRUCTURE_MEMBER_HANDLE:
- result = kLogicalSegmentExtendedLogicalTypeStructureMemberHandle;
- break;
- default:
- result = kLogicalSegmentExtendedLogicalTypeReserved;
- }
- return result;
- }
- LogicalSegmentSpecialTypeLogicalFormat
- GetPathLogicalSegmentSpecialTypeLogicalType(const unsigned char *const cip_path)
- {
- /* OPENER_ASSERT(kSegmentTypeLogicalSegment == GetPathSegmentType(cip_path), "Not a logical segment!\n") */
- OPENER_ASSERT(kSegmentTypeLogicalSegment == GetPathSegmentType(cip_path) );
- OPENER_ASSERT(kLogicalSegmentLogicalTypeSpecial == GetPathLogicalSegmentLogicalType(
- cip_path) );
- const unsigned int kLogicalFormatMask = 0x03;
- const unsigned int logical_format = (*cip_path) & kLogicalFormatMask;
- LogicalSegmentSpecialTypeLogicalFormat result =
- kLogicalSegmentSpecialTypeLogicalFormatReserved;
- switch(logical_format) {
- case LOGICAL_SEGMENT_SPECIAL_TYPE_FORMAT_ELECTRONIC_KEY:
- result = kLogicalSegmentSpecialTypeLogicalFormatElectronicKey;
- break;
- default:
- result = kLogicalSegmentSpecialTypeLogicalFormatReserved;
- break;
- }
- return result;
- }
- ElectronicKeySegmentFormat GetPathLogicalSegmentElectronicKeyFormat(
- const unsigned char *const cip_path) {
- /* OPENER_ASSERT(kLogicalSegmentSpecialTypeLogicalFormatElectronicKey ==
- GetPathLogicalSegmentSpecialTypeLogicalType(cip_path), "Not an electronic key!\n") */
- OPENER_ASSERT(kLogicalSegmentSpecialTypeLogicalFormatElectronicKey == GetPathLogicalSegmentSpecialTypeLogicalType(
- cip_path) );
- ElectronicKeySegmentFormat result = kElectronicKeySegmentFormatReserved;
- switch(*(cip_path + 1) ) {
- case ELECTRONIC_KEY_SEGMENT_KEY_FORMAT_4:
- result = kElectronicKeySegmentFormatKeyFormat4;
- break;
- default:
- result = kElectronicKeySegmentFormatReserved;
- break;
- }
- return result;
- }
- void GetElectronicKeyFormat4FromMessage(const CipOctet **const message,
- ElectronicKeyFormat4 *key) {
- OPENER_ASSERT(kElectronicKeySegmentFormatKeyFormat4 == GetPathLogicalSegmentElectronicKeyFormat(
- *message) );
- (*message) += 2;
- ElectronicKeyFormat4SetVendorId(key, GetUintFromMessage(message) );
- ElectronicKeyFormat4SetDeviceType(key, GetUintFromMessage(message) );
- ElectronicKeyFormat4SetProductCode(key, GetUintFromMessage(message) );
- ElectronicKeyFormat4SetMajorRevisionCompatibility(key,
- GetByteFromMessage(message) );
- ElectronicKeyFormat4SetMinorRevision(key, GetUsintFromMessage(message) );
- }
- /*** Logical Segment ***/
- /*** Network Segment ***/
- /** @brief Return the Network Segment subtype
- *
- * @param cip_path Pointer to the start of the EPath message
- * @return The Network Segment subtype of the EPath
- */
- NetworkSegmentSubtype GetPathNetworkSegmentSubtype(
- const unsigned char *const cip_path) {
- OPENER_ASSERT(kSegmentTypeNetworkSegment == GetPathSegmentType(cip_path) );
- const unsigned int kSubtypeMask = 0x1F;
- const unsigned int subtype = (*cip_path) & kSubtypeMask;
- NetworkSegmentSubtype result = kNetworkSegmentSubtypeReserved;
- switch(subtype) {
- case NETWORK_SEGMENT_SCHEDULE:
- result = kNetworkSegmentSubtypeScheduleSegment;
- break;
- case NETWORK_SEGMENT_FIXED_TAG:
- result = kNetworkSegmentSubtypeFixedTagSegment;
- break;
- case NETWORK_SEGMENT_PRODUCTION_INHIBIT_TIME_IN_MILLISECONDS:
- result = kNetworkSegmentSubtypeProductionInhibitTimeInMilliseconds;
- break;
- case NETWORK_SEGMENT_SAFETY:
- result = kNetworkSegmentSubtypeSafetySegment;
- break;
- case NETWORK_SEGMENT_PRODUCTION_INHIBIT_TIME_IN_MICROSECONDS:
- result = kNetworkSegmentSubtypeProductionInhibitTimeInMicroseconds;
- break;
- case NETWORK_SEGMENT_EXTENDED_NETWORK:
- result = kNetworkSegmentSubtypeExtendedNetworkSegment;
- break;
- default:
- result = kNetworkSegmentSubtypeReserved;
- break;
- }
- return result;
- }
- /**
- * @brief Return the Production Inhibit Time in milliseconds from an EPath
- *
- * @param cip_path Pointer to the start of the EPath message
- * @return the Production Inhibit Time in milliseconds ranging from 0 to 255
- */
- CipUsint GetPathNetworkSegmentProductionInhibitTimeInMilliseconds(
- const unsigned char *const cip_path) {
- /* OPENER_ASSERT(kSegmentTypeNetworkSegment == GetPathSegmentType(cip_path),"Not a network segment!\n")
- OPENER_ASSERT(kNetworkSegmentSubtypeProductionInhibitTimeInMilliseconds == GetPathNetworkSegmentSubtype(cip_path),
- "Not a Production Inhibit Time milliseconds segment!\n") */
- OPENER_ASSERT(kSegmentTypeNetworkSegment == GetPathSegmentType(cip_path) );
- OPENER_ASSERT(kNetworkSegmentSubtypeProductionInhibitTimeInMilliseconds == GetPathNetworkSegmentSubtype(
- cip_path) );
- return *(cip_path + 1);
- }
- /**
- * @brief Return the Production Inhibit Time in microseconds from an EPath
- *
- * @param cip_path Pointer to the start of the EPath message
- * @return the Production Inhibit Time in microseconds ranging from 0 to 4294967295
- */
- CipUdint GetPathNetworkSegmentProductionInhibitTimeInMicroseconds(
- const unsigned char *const cip_path) {
- /* OPENER_ASSERT(kSegmentTypeNetworkSegment == GetPathSegmentType(cip_path),"Not a network segment!\n")
- OPENER_ASSERT(kNetworkSegmentSubtypeProductionInhibitTimeInMicroseconds == GetPathNetworkSegmentSubtype(cip_path),
- "Not a Production Inhibit Time microseconds segment!\n")
- OPENER_ASSERT(2 == *(cip_path + 1), "Data Words length is incorrect! See CIP Spec Vol.1 C-1.4.3.3.2\n") */
- OPENER_ASSERT(kSegmentTypeNetworkSegment == GetPathSegmentType(cip_path) );
- OPENER_ASSERT(kNetworkSegmentSubtypeProductionInhibitTimeInMicroseconds == GetPathNetworkSegmentSubtype(
- cip_path) );
- OPENER_ASSERT(2 == *(cip_path + 1) );
- const unsigned char *message_runner = cip_path + 2;
- return GetUdintFromMessage(&message_runner);
- }
- /*** Network Segment ***/
- /*** Symbolic Segment ***/
- SymbolicSegmentFormat GetPathSymbolicSegmentFormat(
- const unsigned char *const cip_path) {
- const unsigned int kSymbolicSegmentFormatMask = 0x1F;
- if(SYMBOLIC_SEGMENT_FORMAT_EXTENDED_STRING ==
- (*cip_path & kSymbolicSegmentFormatMask) ) {
- return kSymbolicSegmentFormatExtendedString;
- }
- return kSymbolicSegmentFormatASCII;
- }
- unsigned int GetPathSymbolicSegmentASCIIFormatLength(
- const unsigned char *const cip_path) {
- const unsigned int kSymbolicSegmentASCIIFormatLength = 0x1F;
- const unsigned int length = *cip_path & kSymbolicSegmentASCIIFormatLength;
- OPENER_ASSERT(0 != length);
- return length;
- }
- SymbolicSegmentExtendedFormat GetPathSymbolicSegmentNumericType(
- const unsigned char *const cip_path) {
- const unsigned int kSymbolicSegmentExtendedFormatNumericTypeMask = 0x1F;
- const unsigned int numeric_subtype = *(cip_path + 1) &
- kSymbolicSegmentExtendedFormatNumericTypeMask;
- SymbolicSegmentExtendedFormat result = kSymbolicSegmentExtendedFormatReserved;
- switch(numeric_subtype) {
- case SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC_USINT_TYPE:
- result = kSymbolicSegmentExtendedFormatNumericSymbolUSINT;
- break;
- case SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC_UINT_TYPE:
- result = kSymbolicSegmentExtendedFormatNumericSymbolUINT;
- break;
- case SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC_UDINT_TYPE:
- result = kSymbolicSegmentExtendedFormatNumericSymbolUDINT;
- break;
- default:
- result = kSymbolicSegmentExtendedFormatReserved;
- break;
- }
- return result;
- }
- SymbolicSegmentExtendedFormat GetPathSymbolicSegmentExtendedFormat(
- const unsigned char *const cip_path) {
- OPENER_ASSERT(kSegmentTypeSymbolicSegment == GetPathSegmentType(cip_path) );
- OPENER_ASSERT(kSymbolicSegmentFormatExtendedString == GetPathSymbolicSegmentFormat(
- cip_path) );
- const unsigned int kSymbolicSegmentExtendedFormatMask = 0xE0;
- const unsigned int extended_type = *(cip_path + 1) &
- kSymbolicSegmentExtendedFormatMask;
- SymbolicSegmentExtendedFormat result = kSymbolicSegmentExtendedFormatReserved;
- switch(extended_type) {
- case SYMBOLIC_SEGMENT_EXTENDED_FORMAT_DOUBLE_CHAR:
- result = kSymbolicSegmentExtendedFormatDoubleByteChars;
- break;
- case SYMBOLIC_SEGMENT_EXTENDED_FORMAT_TRIPLE_CHAR:
- result = kSymbolicSegmentExtendedFormatTripleByteChars;
- break;
- case SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC:
- result = GetPathSymbolicSegmentNumericType(cip_path);
- break;
- default:
- result = kSymbolicSegmentExtendedFormatReserved;
- break;
- }
- return result;
- }
- /*** Symbolic Segment ***/
- /*** Data Segment ***/
- DataSegmentSubtype GetPathDataSegmentSubtype(const unsigned char *const cip_path)
- {
- const unsigned int kDataSegmentSubtypeMask = 0x1F;
- const unsigned int data_subtype = (*cip_path) & kDataSegmentSubtypeMask;
- DataSegmentSubtype result = kDataSegmentSubtypeReserved;
- switch(data_subtype) {
- case DATA_SEGMENT_SUBTYPE_SIMPLE_DATA:
- result = kDataSegmentSubtypeSimpleData;
- break;
- case DATA_SEGMENT_SUBTYPE_ANSI_EXTENDED_SYMBOL:
- result = kDataSegmentSubtypeANSIExtendedSymbol;
- break;
- default:
- result = kDataSegmentSubtypeReserved;
- break;
- }
- return result;
- }
- /** @brief Returns the amount of 16-bit data words in the Simple Data EPath
- *
- * @param cip_path Pointer to the start of the EPath message
- * @return The amount of 16-bit words of data in the EPath
- */
- CipUsint GetPathDataSegmentSimpleDataWordLength(
- const unsigned char *const cip_path) {
- /* OPENER_ASSERT(kSegmentTypeDataSegment == GetPathSegmentType(cip_path),"Not a data segment!\n");
- OPENER_ASSERT(kDataSegmentSubtypeSimpleData == GetPathDataSegmentSubtype(cip_path), "Not a simple data segment!\n") */
- OPENER_ASSERT(kSegmentTypeDataSegment == GetPathSegmentType(cip_path) );
- OPENER_ASSERT(kDataSegmentSubtypeSimpleData ==
- GetPathDataSegmentSubtype(cip_path) );
- const unsigned char *message_runner = cip_path + 1;
- return GetUsintFromMessage(&message_runner);
- }
- /*** End Data Segment ***/
- /* Special purpose functions */
- LogicalSegmentLogicalFormat CipEpathGetNeededLogicalFormatForValue(
- CipDword value) {
- LogicalSegmentLogicalFormat logical_format =
- kLogicalSegmentLogicalFormatEightBit;
- if(0xFF < value) {
- logical_format = kLogicalSegmentLogicalFormatSixteenBit;
- }
- if(0xFFFF < value) {
- logical_format = kLogicalSegmentLogicalFormatThirtyTwoBit;
- }
- return logical_format;
- }
- //TODO: Does not match the actual interface anymore, check how to fix
- size_t CipEpathEncodeConnectionEpath(
- const CipConnectionPathEpath *const connection_epath,
- CipOctet **encoded_path) {
- size_t encoded_path_length = 0;
- {
- SetPathSegmentType(kSegmentTypeLogicalSegment, *encoded_path);
- SetPathLogicalSegmentLogicalType(kLogicalSegmentLogicalTypeClassId,
- *encoded_path);
- LogicalSegmentLogicalFormat logical_value =
- CipEpathGetNeededLogicalFormatForValue(connection_epath->class_id);
- SetPathLogicalSegmentLogicalFormat(logical_value, *encoded_path);
- encoded_path_length += 1;
- MoveMessageNOctets(1, (const CipOctet **) encoded_path);
- CipEpathSetLogicalValue(connection_epath->class_id,
- logical_value,
- encoded_path);
- }
- {
- SetPathSegmentType(kSegmentTypeLogicalSegment, *encoded_path);
- SetPathLogicalSegmentLogicalType(kLogicalSegmentLogicalTypeClassId,
- *encoded_path);
- LogicalSegmentLogicalFormat logical_value =
- CipEpathGetNeededLogicalFormatForValue(connection_epath->instance_id);
- SetPathLogicalSegmentLogicalFormat(logical_value, *encoded_path);
- encoded_path_length += 1;
- MoveMessageNOctets(1, (const CipOctet **) encoded_path);
- CipEpathSetLogicalValue(connection_epath->instance_id,
- logical_value,
- encoded_path);
- }
- if(0 != connection_epath->attribute_id_or_connection_point) {
- SetPathSegmentType(kSegmentTypeLogicalSegment, *encoded_path);
- SetPathLogicalSegmentLogicalType(kLogicalSegmentLogicalTypeClassId,
- *encoded_path);
- LogicalSegmentLogicalFormat logical_value =
- CipEpathGetNeededLogicalFormatForValue(
- connection_epath->attribute_id_or_connection_point);
- SetPathLogicalSegmentLogicalFormat(logical_value, *encoded_path);
- encoded_path_length += 1;
- MoveMessageNOctets(1, (const CipOctet **) encoded_path);
- CipEpathSetLogicalValue(connection_epath->attribute_id_or_connection_point,
- logical_value,
- encoded_path);
- }
- return encoded_path_length += 1;
- }
- bool CipEpathEqual(const CipOctet *const path1,
- const CipUint path1_length,
- const CipOctet *const path2,
- const CipUint path2_length) {
- if(path1_length != path2_length) {
- return false;
- }
- for(size_t i = 0; i < path1_length; ++i) {
- if(path1[i] != path2[i]) {
- return false;
- }
- }
- return true;
- }
|