dynamic_node_id_client.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Pavel Kirienko <pavel.kirienko@gmail.com>
3  */
4 
5 #include <gtest/gtest.h>
7 #include "helpers.hpp"
8 
9 
10 TEST(DynamicNodeIDClient, Basic)
11 {
12  // Node A is Allocator, Node B is Allocatee
14 
15  uavcan::DynamicNodeIDClient dnidac(nodes.b);
16 
19  (void)_reg1;
20 
21  /*
22  * Client initialization
23  */
24  uavcan::protocol::HardwareVersion::FieldTypes::unique_id unique_id;
25 
26  ASSERT_LE(-uavcan::ErrInvalidParam, dnidac.start(unique_id)); // Empty hardware version is not allowed
27 
28  for (uavcan::uint8_t i = 0; i < unique_id.size(); i++)
29  {
30  unique_id[i] = i;
31  }
32 
33  ASSERT_LE(-uavcan::ErrInvalidParam, dnidac.start(unique_id, uavcan::NodeID()));
34 
35  const uavcan::NodeID PreferredNodeID = 42;
36  ASSERT_LE(0, dnidac.start(unique_id, PreferredNodeID));
37 
38  ASSERT_FALSE(dnidac.getAllocatedNodeID().isValid());
39  ASSERT_FALSE(dnidac.getAllocatorNodeID().isValid());
40  ASSERT_FALSE(dnidac.isAllocationComplete());
41 
42  /*
43  * Subscriber (server emulation)
44  */
46  ASSERT_LE(0, dynid_sub.start());
48 
49  /*
50  * Monitoring requests
51  */
53  ASSERT_TRUE(dynid_sub.collector.msg.get());
54  std::cout << "First-stage request:\n" << *dynid_sub.collector.msg << std::endl;
55  ASSERT_EQ(PreferredNodeID.get(), dynid_sub.collector.msg->node_id);
56  ASSERT_TRUE(dynid_sub.collector.msg->first_part_of_unique_id);
57  ASSERT_TRUE(uavcan::equal(dynid_sub.collector.msg->unique_id.begin(),
58  dynid_sub.collector.msg->unique_id.end(),
59  unique_id.begin()));
60  dynid_sub.collector.msg.reset();
61 
62  // Second - rate is no lower than 0.5 Hz
64  ASSERT_TRUE(dynid_sub.collector.msg.get());
65  dynid_sub.collector.msg.reset();
66 
67  ASSERT_FALSE(dnidac.getAllocatedNodeID().isValid());
68  ASSERT_FALSE(dnidac.getAllocatorNodeID().isValid());
69  ASSERT_FALSE(dnidac.isAllocationComplete());
70 
71  /*
72  * Publisher (server emulation)
73  */
75  ASSERT_LE(0, dynid_pub.init());
76 
77  /*
78  * Sending some some Allocation messages - the timer will keep restarting
79  */
80  for (int i = 0; i < 10; i++)
81  {
82  uavcan::protocol::dynamic_node_id::Allocation msg; // Contents of the message doesn't matter
83  ASSERT_LE(0, dynid_pub.broadcast(msg));
85  ASSERT_FALSE(dynid_sub.collector.msg.get());
86  }
87 
88  /*
89  * Responding with partially matching unique ID - the client will respond with second-stage request immediately
90  */
91  const uint8_t BytesPerRequest = uavcan::protocol::dynamic_node_id::Allocation::MAX_LENGTH_OF_UNIQUE_ID_IN_REQUEST;
92  {
93  uavcan::protocol::dynamic_node_id::Allocation msg;
94  msg.unique_id.resize(BytesPerRequest);
95  uavcan::copy(unique_id.begin(), unique_id.begin() + BytesPerRequest, msg.unique_id.begin());
96 
97  std::cout << "First-stage offer:\n" << msg << std::endl;
98 
99  ASSERT_FALSE(dynid_sub.collector.msg.get());
100  ASSERT_LE(0, dynid_pub.broadcast(msg));
102 
103  ASSERT_TRUE(dynid_sub.collector.msg.get());
104  std::cout << "Second-stage request:\n" << *dynid_sub.collector.msg << std::endl;
105  ASSERT_EQ(PreferredNodeID.get(), dynid_sub.collector.msg->node_id);
106  ASSERT_FALSE(dynid_sub.collector.msg->first_part_of_unique_id);
107  ASSERT_TRUE(uavcan::equal(dynid_sub.collector.msg->unique_id.begin(),
108  dynid_sub.collector.msg->unique_id.end(),
109  unique_id.begin() + BytesPerRequest));
110  dynid_sub.collector.msg.reset();
111  }
112 
113  /*
114  * Responding with second-stage offer, expecting the last request back
115  */
116  {
117  uavcan::protocol::dynamic_node_id::Allocation msg;
118  msg.unique_id.resize(BytesPerRequest * 2);
119  uavcan::copy(unique_id.begin(), unique_id.begin() + BytesPerRequest * 2, msg.unique_id.begin());
120 
121  std::cout << "Second-stage offer:\n" << msg << std::endl;
122 
123  ASSERT_FALSE(dynid_sub.collector.msg.get());
124  ASSERT_LE(0, dynid_pub.broadcast(msg));
126 
127  ASSERT_TRUE(dynid_sub.collector.msg.get());
128  std::cout << "Last request:\n" << *dynid_sub.collector.msg << std::endl;
129  ASSERT_EQ(PreferredNodeID.get(), dynid_sub.collector.msg->node_id);
130  ASSERT_FALSE(dynid_sub.collector.msg->first_part_of_unique_id);
131  ASSERT_TRUE(uavcan::equal(dynid_sub.collector.msg->unique_id.begin(),
132  dynid_sub.collector.msg->unique_id.end(),
133  unique_id.begin() + BytesPerRequest * 2));
134  dynid_sub.collector.msg.reset();
135  }
136 
137  ASSERT_FALSE(dnidac.getAllocatedNodeID().isValid());
138  ASSERT_FALSE(dnidac.getAllocatorNodeID().isValid());
139  ASSERT_FALSE(dnidac.isAllocationComplete());
140 
141  /*
142  * Now we have full unique ID for this client received, and it is possible to grant allocation
143  */
144  {
145  uavcan::protocol::dynamic_node_id::Allocation msg;
146  msg.unique_id.resize(16);
147  msg.node_id = 72;
148  uavcan::copy(unique_id.begin(), unique_id.end(), msg.unique_id.begin());
149 
150  ASSERT_FALSE(dynid_sub.collector.msg.get());
151  ASSERT_LE(0, dynid_pub.broadcast(msg));
153  ASSERT_FALSE(dynid_sub.collector.msg.get());
154  }
155 
156  ASSERT_EQ(uavcan::NodeID(72), dnidac.getAllocatedNodeID());
157  ASSERT_EQ(uavcan::NodeID(10), dnidac.getAllocatorNodeID());
158  ASSERT_TRUE(dnidac.isAllocationComplete());
159 }
160 
161 
162 TEST(DynamicNodeIDClient, NonPassiveMode)
163 {
165 
166  uavcan::DynamicNodeIDClient dnidac(nodes.b);
167 
170  (void)_reg1;
171 
172  uavcan::protocol::HardwareVersion::FieldTypes::unique_id unique_id;
173  for (uavcan::uint8_t i = 0; i < unique_id.size(); i++)
174  {
175  unique_id[i] = i;
176  }
177 
178  ASSERT_LE(-uavcan::ErrLogic, dnidac.start(unique_id));
179 }
uavcan::NodeID::isValid
bool isValid() const
Definition: transfer.hpp:134
uavcan::DefaultDataTypeRegistrator
Definition: global_data_type_registry.hpp:186
uavcan::DynamicNodeIDClient::start
int start(const UniqueID &unique_id, const NodeID preferred_node_id=NodeID::Broadcast, const TransferPriority transfer_priority=TransferPriority::OneHigherThanLowest)
Definition: uc_dynamic_node_id_client.cpp:147
uavcan::Publisher
Definition: publisher.hpp:18
SubscriberWithCollector
Definition: libuavcan/libuavcan/test/protocol/helpers.hpp:33
uavcan::NodeID::get
uint8_t get() const
Definition: transfer.hpp:132
uavcan::NodeID
Definition: transfer.hpp:112
uavcan::DurationBase< MonotonicDuration >::fromMSec
static MonotonicDuration fromMSec(int64_t ms)
Definition: time.hpp:41
TEST
TEST(DynamicNodeIDClient, Basic)
Definition: dynamic_node_id_client.cpp:10
uavcan::DynamicNodeIDClient::isAllocationComplete
bool isAllocationComplete() const
Definition: dynamic_node_id_client.hpp:94
SubscriberWithCollector::start
int start()
Definition: libuavcan/libuavcan/test/protocol/helpers.hpp:45
uavcan_kinetis::ErrLogic
static const uavcan::int16_t ErrLogic
Internal logic error.
Definition: platform_specific_components/kinetis/libuavcan/driver/include/uavcan_kinetis/can.hpp:22
uavcan::uint8_t
std::uint8_t uint8_t
Definition: std.hpp:24
SubscriberWithCollector::subscriber
Subscriber subscriber
Definition: libuavcan/libuavcan/test/protocol/helpers.hpp:39
helpers.hpp
uavcan::equal
UAVCAN_EXPORT bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2)
Definition: templates.hpp:324
uavcan::DynamicNodeIDClient
Definition: dynamic_node_id_client.hpp:31
InterlinkedTestNodes
Definition: test_node.hpp:149
SubscriberWithCollector::collector
Collector collector
Definition: libuavcan/libuavcan/test/protocol/helpers.hpp:38
uavcan::NodeID::Broadcast
static const NodeID Broadcast
Definition: transfer.hpp:122
uavcan::DynamicNodeIDClient::getAllocatedNodeID
NodeID getAllocatedNodeID() const
Definition: dynamic_node_id_client.hpp:102
dynamic_node_id_client.hpp
uavcan::GenericPublisher< DataType_, DataType_ >::init
int init()
Definition: generic_publisher.hpp:118
InterlinkedTestNodes::a
TestNode a
Definition: test_node.hpp:155
SubscriptionCollector::msg
std::unique_ptr< DataType > msg
Definition: libuavcan/libuavcan/test/protocol/helpers.hpp:23
InterlinkedTestNodes::spinBoth
int spinBoth(uavcan::MonotonicDuration duration)
Definition: test_node.hpp:176
uavcan::Publisher::broadcast
int broadcast(const DataType &message)
Definition: publisher.hpp:52
uavcan::GlobalDataTypeRegistry::instance
static GlobalDataTypeRegistry & instance()
Definition: uc_global_data_type_registry.cpp:128
uavcan::DynamicNodeIDClient::getAllocatorNodeID
NodeID getAllocatorNodeID() const
Definition: dynamic_node_id_client.hpp:110
uavcan::copy
UAVCAN_EXPORT OutputIt copy(InputIt first, InputIt last, OutputIt result)
Definition: templates.hpp:238
InterlinkedTestNodes::b
TestNode b
Definition: test_node.hpp:156
uavcan::GenericSubscriber::allowAnonymousTransfers
void allowAnonymousTransfers()
Definition: generic_subscriber.hpp:204


uavcan_communicator
Author(s):
autogenerated on Fri Dec 13 2024 03:10:02