libuav original
Dependents: UAVCAN UAVCAN_Subscriber
uc_data_type.cpp
00001 /* 00002 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com> 00003 */ 00004 00005 #include <uavcan/data_type.hpp> 00006 #include <uavcan/transport/crc.hpp> 00007 #include <cstring> 00008 #include <cassert> 00009 00010 namespace uavcan 00011 { 00012 /* 00013 * DataTypeID 00014 */ 00015 const uint16_t DataTypeID::MaxServiceDataTypeIDValue; 00016 const uint16_t DataTypeID::MaxMessageDataTypeIDValue; 00017 const uint16_t DataTypeID::MaxPossibleDataTypeIDValue; 00018 00019 DataTypeID DataTypeID::getMaxValueForDataTypeKind(const DataTypeKind dtkind) 00020 { 00021 if (dtkind == DataTypeKindService) 00022 { 00023 return MaxServiceDataTypeIDValue; 00024 } 00025 else if (dtkind == DataTypeKindMessage) 00026 { 00027 return MaxMessageDataTypeIDValue; 00028 } 00029 else 00030 { 00031 UAVCAN_ASSERT(0); 00032 return DataTypeID(0); 00033 } 00034 } 00035 00036 /* 00037 * DataTypeSignatureCRC 00038 */ 00039 DataTypeSignatureCRC DataTypeSignatureCRC::extend(uint64_t crc) 00040 { 00041 DataTypeSignatureCRC ret; 00042 ret.crc_ = crc ^ 0xFFFFFFFFFFFFFFFF; 00043 return ret; 00044 } 00045 00046 void DataTypeSignatureCRC::add(uint8_t byte) 00047 { 00048 static const uint64_t Poly = 0x42F0E1EBA9EA3693; 00049 crc_ ^= uint64_t(byte) << 56; 00050 for (int i = 0; i < 8; i++) 00051 { 00052 crc_ = (crc_ & (uint64_t(1) << 63)) ? (crc_ << 1) ^ Poly : crc_ << 1; 00053 } 00054 } 00055 00056 void DataTypeSignatureCRC::add(const uint8_t* bytes, unsigned len) 00057 { 00058 UAVCAN_ASSERT(bytes); 00059 while (len--) 00060 { 00061 add(*bytes++); 00062 } 00063 } 00064 00065 /* 00066 * DataTypeSignature 00067 */ 00068 void DataTypeSignature::mixin64(uint64_t x) 00069 { 00070 DataTypeSignatureCRC crc = DataTypeSignatureCRC::extend(value_); 00071 for (int i = 0; i < 64; i += 8) // LSB first 00072 { 00073 crc.add((x >> i) & 0xFF); 00074 } 00075 value_ = crc.get(); 00076 } 00077 00078 void DataTypeSignature::extend(DataTypeSignature dts) 00079 { 00080 const uint64_t y = value_; 00081 mixin64(dts.get()); 00082 mixin64(y); 00083 } 00084 00085 TransferCRC DataTypeSignature::toTransferCRC() const 00086 { 00087 TransferCRC tcrc; 00088 for (int i = 0; i < 64; i += 8) // LSB first 00089 { 00090 tcrc.add((value_ >> i) & 0xFF); 00091 } 00092 return tcrc; 00093 } 00094 00095 /* 00096 * DataTypeDescriptor 00097 */ 00098 const unsigned DataTypeDescriptor::MaxFullNameLen; 00099 00100 bool DataTypeDescriptor::isValid() const 00101 { 00102 return id_.isValidForDataTypeKind(kind_) && 00103 (full_name_ != UAVCAN_NULLPTR) && 00104 (*full_name_ != '\0'); 00105 } 00106 00107 bool DataTypeDescriptor::match(DataTypeKind kind, const char* name) const 00108 { 00109 return (kind_ == kind) && !std::strncmp(full_name_, name, MaxFullNameLen); 00110 } 00111 00112 bool DataTypeDescriptor::match(DataTypeKind kind, DataTypeID id) const 00113 { 00114 return (kind_ == kind) && (id_ == id); 00115 } 00116 00117 #if UAVCAN_TOSTRING 00118 std::string DataTypeDescriptor::toString() const 00119 { 00120 char kindch = '?'; 00121 switch (kind_) 00122 { 00123 case DataTypeKindMessage: 00124 { 00125 kindch = 'm'; 00126 break; 00127 } 00128 case DataTypeKindService: 00129 { 00130 kindch = 's'; 00131 break; 00132 } 00133 default: 00134 { 00135 UAVCAN_ASSERT(0); 00136 break; 00137 } 00138 } 00139 00140 char buf[128]; 00141 (void)snprintf(buf, sizeof(buf), "%s:%u%c:%016llx", 00142 full_name_, static_cast<unsigned>(id_.get()), kindch, 00143 static_cast<unsigned long long>(signature_.get())); 00144 return std::string(buf); 00145 } 00146 #endif 00147 00148 bool DataTypeDescriptor::operator==(const DataTypeDescriptor& rhs) const 00149 { 00150 return 00151 (kind_ == rhs.kind_) && 00152 (id_ == rhs.id_) && 00153 (signature_ == rhs.signature_) && 00154 !std::strncmp(full_name_, rhs.full_name_, MaxFullNameLen); 00155 } 00156 00157 }
Generated on Tue Jul 12 2022 17:17:35 by
1.7.2