diff --git a/dsdl/uavcan/equipment/gnss/702.RTCMStream.uavcan b/dsdl/uavcan/equipment/gnss/702.RTCMStream.uavcan index b2a2e4354a..389316a01b 100644 --- a/dsdl/uavcan/equipment/gnss/702.RTCMStream.uavcan +++ b/dsdl/uavcan/equipment/gnss/702.RTCMStream.uavcan @@ -8,4 +8,4 @@ uint8 PROTOCOL_ID_RTCM2 = 2 uint8 PROTOCOL_ID_RTCM3 = 3 uint8 protocol_id -uint8[<=400] data +uint8[<=100] data diff --git a/libuavcan/test/dsdl_test/dsdl_uavcan_compilability.cpp b/libuavcan/test/dsdl_test/dsdl_uavcan_compilability.cpp index 852f79a208..49eb313ea8 100644 --- a/libuavcan/test/dsdl_test/dsdl_uavcan_compilability.cpp +++ b/libuavcan/test/dsdl_test/dsdl_uavcan_compilability.cpp @@ -41,7 +41,7 @@ TEST(Dsdl, Streaming) os << get_node_info_rsp << std::endl << "==========" << std::endl; root_ns_a::Deep ps; - ps.a.resize(2); + ps.a.resize(1); os << ps << std::endl << "==========" << std::endl; static const std::string Reference = @@ -81,45 +81,19 @@ TEST(Dsdl, Streaming) " scalar: 0\n" " vector: \n" " - \n" - " vector: [0, 0, 0, 0]\n" + " vector: [0, 0]\n" " bools: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n" " - \n" - " vector: [0, 0, 0, 0]\n" - " bools: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n" - " - \n" - " vector: [0, 0, 0, 0]\n" - " bools: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n" - " - \n" - " scalar: 0\n" - " vector: \n" - " - \n" - " vector: [0, 0, 0, 0]\n" - " bools: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n" - " - \n" - " vector: [0, 0, 0, 0]\n" - " bools: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n" - " - \n" - " vector: [0, 0, 0, 0]\n" + " vector: [0, 0]\n" " bools: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n" "b: \n" " - \n" - " vector: [0, 0, 0, 0]\n" + " vector: [0, 0]\n" " bools: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n" " - \n" - " vector: [0, 0, 0, 0]\n" - " bools: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n" - " - \n" - " vector: [0, 0, 0, 0]\n" + " vector: [0, 0]\n" " bools: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n" "==========\n"; std::cout << os.str(); ASSERT_EQ(Reference, os.str()); } - - -TEST(Dsdl, OStream) -{ - root_ns_a::Deep ps; - ps.a.resize(2); - uavcan::OStream::instance() << ps << uavcan::OStream::endl; -} diff --git a/libuavcan/test/dsdl_test/root_ns_a/A.uavcan b/libuavcan/test/dsdl_test/root_ns_a/A.uavcan index 964e96e285..9f69a474e8 100644 --- a/libuavcan/test/dsdl_test/root_ns_a/A.uavcan +++ b/libuavcan/test/dsdl_test/root_ns_a/A.uavcan @@ -5,4 +5,4 @@ # float32 scalar -B[3] vector +B[2] vector diff --git a/libuavcan/test/dsdl_test/root_ns_a/B.uavcan b/libuavcan/test/dsdl_test/root_ns_a/B.uavcan index 751556b581..9b88d0fa54 100644 --- a/libuavcan/test/dsdl_test/root_ns_a/B.uavcan +++ b/libuavcan/test/dsdl_test/root_ns_a/B.uavcan @@ -1,2 +1,2 @@ -float64[4] vector +float64[2] vector bool[16] bools \ No newline at end of file diff --git a/libuavcan/test/dsdl_test/root_ns_a/Deep.uavcan b/libuavcan/test/dsdl_test/root_ns_a/Deep.uavcan index a45b09c3f0..425e9d26c8 100644 --- a/libuavcan/test/dsdl_test/root_ns_a/Deep.uavcan +++ b/libuavcan/test/dsdl_test/root_ns_a/Deep.uavcan @@ -3,6 +3,6 @@ # bool c -uint8[<64] str -A[<3] a -B[3] b +uint8[<20] str +A[<2] a +B[2] b diff --git a/pyuavcan/pyuavcan/dsdl/parser.py b/pyuavcan/pyuavcan/dsdl/parser.py index 39f74fd449..acffb041d8 100644 --- a/pyuavcan/pyuavcan/dsdl/parser.py +++ b/pyuavcan/pyuavcan/dsdl/parser.py @@ -22,8 +22,12 @@ except NameError: long = int MAX_FULL_TYPE_NAME_LEN = 80 -DATA_TYPE_ID_MAX = 2047 # TODO: different limits for messages and services -MAX_DATA_STRUCT_LEN_BYTES = 439 # TODO: different limits for messages and services + +SERVICE_DATA_TYPE_ID_MAX = 511 +MESSAGE_DATA_TYPE_ID_MAX = 2047 + +MAX_SERVICE_STRUCT_LEN_BYTES = 439 +MAX_MESSAGE_STRUCT_LEN_BYTES = 126 # Broadcast class Type: ''' @@ -286,7 +290,6 @@ class Parser: default_dtid = int(default_dtid) except ValueError: error('Invalid default data type ID [%s]', default_dtid) - validate_data_type_id(default_dtid) full_name = self._namespace_from_filename(filename) + '.' + name validate_compound_type_full_name(full_name) return full_name, default_dtid @@ -492,6 +495,7 @@ class Parser: max_bitlen = t.get_max_bitlen() max_bytelen = bitlen_to_bytelen(max_bitlen) + validate_data_type_id(t) validate_data_struct_len(t) self.log.info('Type [%s], default DTID: %s, signature: %08x, maxbits: %s, maxbytes: %s, DSSD:', full_typename, default_dtid, t.get_dsdl_signature(), max_bitlen, max_bytelen) @@ -560,19 +564,35 @@ def validate_compound_type_full_name(name): def validate_attribute_name(name): enforce(re.match(r'[a-zA-Z][a-zA-Z0-9_]*$', name), 'Invalid attribute name [%s]', name) -def validate_data_type_id(dtid): - enforce(0 <= dtid <= DATA_TYPE_ID_MAX, 'Invalid data type ID [%s]', dtid) +def validate_data_type_id(t): + if t.default_dtid is None: + return + if t.kind == t.KIND_MESSAGE: + enforce(0 <= t.default_dtid <= MESSAGE_DATA_TYPE_ID_MAX, + 'Invalid data type ID for message [%s]', t.default_dtid) + elif t.kind == t.KIND_SERVICE: + enforce(0 <= t.default_dtid <= SERVICE_DATA_TYPE_ID_MAX, + 'Invalid data type ID for service [%s]', t.default_dtid) + else: + error('Invalid kind: %s', t.kind) def validate_data_struct_len(t): enforce(t.category == t.CATEGORY_COMPOUND, 'Data structure length can be enforced only for compound types') + # EXtracting sizes if t.kind == t.KIND_MESSAGE: bitlens = [t.get_max_bitlen()] elif t.kind == t.KIND_SERVICE: bitlens = t.get_max_bitlen_request(), t.get_max_bitlen_response() + # Detecting the limit + if t.kind == t.KIND_MESSAGE and t.default_dtid is not None: + max_bytes = MAX_MESSAGE_STRUCT_LEN_BYTES + else: + max_bytes = MAX_SERVICE_STRUCT_LEN_BYTES + # Checking for bitlen in bitlens: bytelen = bitlen_to_bytelen(bitlen) - enforce(0 <= bytelen <= MAX_DATA_STRUCT_LEN_BYTES, - 'Max data structure length is invalid: %d bits, %d bytes', bitlen, bytelen) + enforce(0 <= bytelen <= max_bytes, + 'Max data structure length is invalid: %d bits, %d bytes; limit %d bytes', bitlen, bytelen, max_bytes) def parse_namespaces(source_dirs, search_dirs=None):