libuav original

Dependents:   UAVCAN UAVCAN_Subscriber

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers uc_data_type.cpp Source File

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 }