service_server.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
3  */
4 
5 #ifndef UAVCAN_NODE_SERVICE_SERVER_HPP_INCLUDED
6 #define UAVCAN_NODE_SERVICE_SERVER_HPP_INCLUDED
7 
11 
12 #if !defined(UAVCAN_CPP_VERSION) || !defined(UAVCAN_CPP11)
13 # error UAVCAN_CPP_VERSION
14 #endif
15 
16 #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
17 # include <functional>
18 #endif
19 
20 namespace uavcan
21 {
39 template <typename ResponseDataType_>
40 class ServiceResponseDataStructure : public ResponseDataType_
41 {
42  // Fields are weirdly named to avoid name clashing with the inherited data type
43  bool _enabled_;
44 
45 public:
46  typedef ResponseDataType_ ResponseDataType;
47 
49  : _enabled_(true)
50  { }
51 
56  void setResponseEnabled(bool x) { _enabled_ = x; }
57 
61  bool isResponseEnabled() const { return _enabled_; }
62 };
63 
81 template <typename DataType_,
82 #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
83  typename Callback_ = std::function<void (const ReceivedDataStructure<typename DataType_::Request>&,
85 #else
86  typename Callback_ = void (*)(const ReceivedDataStructure<typename DataType_::Request>&,
88 #endif
89  >
92 {
93 public:
94  typedef DataType_ DataType;
95  typedef typename DataType::Request RequestType;
96  typedef typename DataType::Response ResponseType;
97  typedef Callback_ Callback;
98 
99 private:
102 
103  PublisherType publisher_;
104  Callback callback_;
106 
108  {
110 
112 
113  if (coerceOrFallback<bool>(callback_, true))
114  {
115  UAVCAN_ASSERT(response.isResponseEnabled()); // Enabled by default
116  callback_(request, response);
117  }
118  else
119  {
120  handleFatalError("Srv serv clbk");
121  }
122 
123  if (response.isResponseEnabled())
124  {
125  publisher_.setPriority(request.getPriority()); // Responding at the same priority.
126 
127  const int res = publisher_.publish(response, TransferTypeServiceResponse, request.getSrcNodeID(),
128  request.getTransferID());
129  if (res < 0)
130  {
131  UAVCAN_TRACE("ServiceServer", "Response publication failure: %i", res);
133  response_failure_count_++;
134  }
135  }
136  else
137  {
138  UAVCAN_TRACE("ServiceServer", "Response was suppressed by the application");
139  }
140  }
141 
142 public:
144  : SubscriberType(node)
145  , publisher_(node, getDefaultTxTimeout())
146  , callback_()
147  , response_failure_count_(0)
148  {
149  UAVCAN_ASSERT(getTxTimeout() == getDefaultTxTimeout()); // Making sure it is valid
150 
151  StaticAssert<DataTypeKind(DataType::DataTypeKind) == DataTypeKindService>::check();
152  }
153 
158  int start(const Callback& callback)
159  {
160  stop();
161 
162  if (!coerceOrFallback<bool>(callback, true))
163  {
164  UAVCAN_TRACE("ServiceServer", "Invalid callback");
165  return -ErrInvalidParam;
166  }
167  callback_ = callback;
168 
169  const int publisher_res = publisher_.init();
170  if (publisher_res < 0)
171  {
172  UAVCAN_TRACE("ServiceServer", "Publisher initialization failure: %i", publisher_res);
173  return publisher_res;
174  }
175  return SubscriberType::startAsServiceRequestListener();
176  }
177 
181  using SubscriberType::stop;
182 
184  static MonotonicDuration getMinTxTimeout() { return PublisherType::getMinTxTimeout(); }
185  static MonotonicDuration getMaxTxTimeout() { return PublisherType::getMaxTxTimeout(); }
186 
187  MonotonicDuration getTxTimeout() const { return publisher_.getTxTimeout(); }
188  void setTxTimeout(MonotonicDuration tx_timeout) { publisher_.setTxTimeout(tx_timeout); }
189 
195  uint32_t getRequestFailureCount() const { return SubscriberType::getFailureCount(); }
196  uint32_t getResponseFailureCount() const { return response_failure_count_; }
197 };
198 
199 }
200 
201 #endif // UAVCAN_NODE_SERVICE_SERVER_HPP_INCLUDED
MonotonicDuration getTxTimeout() const
void setPriority(const TransferPriority prio)
uint32_t getResponseFailureCount() const
GenericPublisher< DataType, ResponseType > PublisherType
Dispatcher & getDispatcher()
uint32_t getRequestFailureCount() const
UAVCAN_EXPORT void handleFatalError(const char *msg)
Definition: uc_error.cpp:20
static MonotonicDuration getDefaultTxTimeout()
virtual void handleReceivedDataStruct(ReceivedDataStructure< RequestType > &request)
void setTxTimeout(MonotonicDuration tx_timeout)
void setTxTimeout(MonotonicDuration tx_timeout)
std::uint32_t uint32_t
Definition: std.hpp:26
const TransferPerfCounter & getTransferPerfCounter() const
Definition: dispatcher.hpp:236
static MonotonicDuration getMaxTxTimeout()
DataType::Request RequestType
GenericSubscriber< DataType, RequestType, TransferListener > SubscriberType
int start(const Callback &callback)
int publish(const DataStruct &message, TransferType transfer_type, NodeID dst_node_id, MonotonicTime blocking_deadline=MonotonicTime())
DataType::Response ResponseType
static MonotonicDuration fromMSec(int64_t ms)
Definition: time.hpp:41
TransferPriority getPriority() const
const std::string response
MonotonicDuration getTxTimeout() const
static MonotonicDuration getMinTxTimeout()
TransferType getTransferType() const


uavcan_communicator
Author(s):
autogenerated on Wed Jan 11 2023 03:59:39