VSM C++ SDK
Vehicle Specific Modules SDK
device.h
1 /*
2  * device.h
3  *
4  * Created on: May 5, 2016
5  * Author: janis
6  */
7 
8 #ifndef SRC_DEVICE_H_
9 #define SRC_DEVICE_H_
10 
11 #include <memory>
12 #include <unordered_map>
13 #include <unordered_set>
14 #include <ugcs/vsm/property.h>
15 #include <ugcs/vsm/callback.h>
17 #include <ugcs/vsm/optional.h>
18 #include <ugcs/vsm/vehicle_requests.h> // deprecated
19 
20 namespace ugcs {
21 namespace vsm {
22 
23 typedef std::shared_ptr<ugcs::vsm::proto::Vsm_message> Proto_msg_ptr;
24 
25 class Vsm_command: public std::enable_shared_from_this<Vsm_command>
26 {
28 public:
29 
30  Vsm_command(std::string name, bool as_command, bool in_mission);
31 
32  Property::Ptr
33  Add_parameter(
34  std::string,
35  ugcs::vsm::proto::Field_semantic semantic = ugcs::vsm::proto::FIELD_SEMANTIC_DEFAULT);
36 
37  Property::Ptr
38  Add_parameter(std::string name, Property::Value_type type);
39 
40  // Fill registration message
41  void
42  Register(ugcs::vsm::proto::Register_command* command);
43 
44  // Fill availability message
45  void
46  Set_capabilities(ugcs::vsm::proto::Command_availability* msg);
47 
48  void
49  Set_enabled(bool is_enabled = true);
50 
51  void
52  Set_available(bool is_available = true);
53 
54  int
55  Get_id() {return command_id;};
56 
57  bool
58  Is_capability_state_dirty() {return capability_state_dirty;};
59 
60  // create a list of command param values from proto message
62  Build_parameter_list(const ugcs::vsm::proto::Device_command &cmd);
63 
64  std::string
65  Get_name()
66  {return name;};
67 
68  bool
69  Is_mission_item()
70  {return in_mission;};
71 
72 private:
73  uint32_t command_id = 0;
74  std::unordered_map<int, Property::Ptr> parameters;
75  std::string name;
76 
77  bool as_command = false;
78  bool in_mission = false;
79 
80  bool is_available = false;
81  bool is_enabled = false;
82  bool capability_state_dirty = true;
83  friend class Device;
84 };
85 
86 class Ucs_request :public Request
87 {
89 public:
90 
91  Ucs_request(ugcs::vsm::proto::Vsm_message);
92 
93  void
94  Add_command(Vsm_command::Ptr cmd);
95 
96  void
97  Complete(ugcs::vsm::proto::Status_code = ugcs::vsm::proto::STATUS_OK, const std::string& description = std::string());
98 
99  Proto_msg_ptr response;
100  ugcs::vsm::proto::Vsm_message request;
101 };
102 
103 class Device: public std::enable_shared_from_this<Device>
104 {
105  DEFINE_COMMON_CLASS(Device, Device)
106 public:
107 
108  Device(bool create_thread = true);
109 
110  typedef Callback_proxy<
111  void,
112  std::vector<Property::Ptr>>
114 
115  virtual
116  ~Device();
117 
123  void
124  Enable();
125 
129  void
130  Disable();
131 
133  bool
134  Is_enabled() { return is_enabled;};
135 
137  Device(const Device &) = delete;
138 
144  void
145  Process_requests();
146 
149 
150  void
151  On_ucs_message(
152  ugcs::vsm::proto::Vsm_message message,
153  Response_sender completion_handler = Response_sender(),
154  ugcs::vsm::Request_completion_context::Ptr completion_ctx = nullptr
155  );
156 
157  // Used by Cucs_processor only.
158  // Derived class must override.
159  virtual void
160  Fill_register_msg(ugcs::vsm::proto::Vsm_message&) = 0;
161 
162  template<typename Type>
163  void
164  Add_property(
165  const std::string& name,
166  Type value,
167  Property::Value_type value_type)
168  {
169  if (properties.find(name) != properties.end()) {
170  VSM_EXCEPTION(Exception, "Property %s already added", name.c_str());
171  }
172  auto f = Property::Create(name, value, value_type);
173  properties.emplace(name, f);
174  }
175 
176  template<typename Type>
177  void
178  Add_property(
179  const std::string& name,
180  ugcs::vsm::proto::Field_semantic semantic,
181  Type value)
182  {
183  if (properties.find(name) != properties.end()) {
184  VSM_EXCEPTION(Exception, "Property %s already added", name.c_str());
185  }
186  auto f = Property::Create(name, semantic, value);
187  properties.emplace(name, f);
188  }
189 
190  uint32_t
191  Get_session_id();
192 
195  Get_completion_ctx();
196 
197 protected:
198 
202  void
203  Register();
204 
206  void
207  Unregister();
208 
211  Get_processing_ctx();
212 
216  virtual void
218  {};
219 
223  virtual void
225  {};
226 
232  virtual void
233  Handle_ucs_command(
234  Ucs_request::Ptr request);
235 
236  void
237  Send_ucs_message(Proto_msg_ptr msg);
238 
240  Get_command(int id);
241 
243  Add_telemetry(
244  const std::string& name,
245  ugcs::vsm::proto::Field_semantic sem = ugcs::vsm::proto::FIELD_SEMANTIC_DEFAULT,
246  uint32_t timeout = 0 // timeout in seconds. default: do not specify timeout
247  );
248 
250  Add_telemetry(
251  const std::string& name,
252  Property::Value_type type,
253  uint32_t timeout = 0 // timeout in seconds. default: do not specify timeout
254  );
255 
256  void
257 
258  // Remove previously added telemetry field.
259  // Invalidates the t_field.
260  Remove_telemetry(Property::Ptr& t_field);
261 
263  Add_command(
264  const std::string& name,
265  bool as_command,
266  bool in_mission);
267 
268  Request_completion_context::Ptr completion_ctx;
269  Request_processor::Ptr processor;
270  std::chrono::time_point<std::chrono::system_clock> begin_of_epoch;
271  // All properties.
272  std::unordered_map<std::string, Property::Ptr> properties;
273 
274  void
275  Add_status_message(const std::string& m);
276 
278  {
279  public:
280  Commit_scope(Device& d):d(d){};
281  ~Commit_scope(){d.Commit_to_ucs();};
282  private:
283  Device& d;
284  };
285 
286  // Add this in each scope which requires a call to Commit_to_ucs().
287  // This guarantees the commit on scope leave and you do not need to
288  // add Commit_to_ucs() before each return.
289  #define CREATE_COMMIT_SCOPE auto auto_device_commit_scope = Commit_scope(*this)
290 
291  void
292  Commit_to_ucs();
293 
294 private:
295 
296  Request_worker::Ptr worker;
297 
298  // All registered telemetry fields.
299  std::vector<Property::Ptr> telemetry_fields;
300  // All commands supported by device
301  std::unordered_map<int, Vsm_command::Ptr> commands;
302  // Status messages to be sent to ucs.
303  std::list<std::string> device_status_messages;
304 
305  uint32_t my_handle = 0;
306 
308  bool is_enabled = false;
309 };
310 
313 #define DEVICE_LOG(level_, vehicle_, fmt_, ...) \
314  _LOG_WRITE_MSG(level_, "[%d] " fmt_, \
315  (vehicle_).Get_session_id(), ## __VA_ARGS__)
316 
319 // @{
320 #define DEVICE_LOG_DBG(vehicle_, fmt_, ...) \
321  DEVICE_LOG(::ugcs::vsm::Log::Level::DEBUGGING, vehicle_, fmt_, ## __VA_ARGS__)
322 
323 #define DEVICE_LOG_INF(vehicle_, fmt_, ...) \
324  DEVICE_LOG(::ugcs::vsm::Log::Level::INFO, vehicle_, fmt_, ## __VA_ARGS__)
325 
326 #define DEVICE_LOG_WRN(vehicle_, fmt_, ...) \
327  DEVICE_LOG(::ugcs::vsm::Log::Level::WARNING, vehicle_, fmt_, ## __VA_ARGS__)
328 
329 #define DEVICE_LOG_ERR(vehicle_, fmt_, ...) \
330  DEVICE_LOG(::ugcs::vsm::Log::Level::ERROR, vehicle_, fmt_, ## __VA_ARGS__)
331 // @}
332 
333 } /* namespace vsm */
334 } /* namespace ugcs */
335 
336 #endif /* SRC_DEVICE_H_ */
UGCS root namespace.
Definition: android-linux/ugcs/vsm/platform_sockets.h:27
static Ptr Create(Args &&...args)
Create an instance.
Definition: property.h:21
Generic request for implementing inter-threads communications and asynchronous operations.
Definition: request_container.h:37
Request worker.
Callback_proxy< void, uint32_t, Proto_msg_ptr > Response_sender
Completion handler type of the request.
Definition: device.h:148
Definition: property.h:191
std::shared_ptr< Property > Ptr
Pointer type.
Definition: property.h:21
virtual void On_enable()
Device enable event handler.
Definition: device.h:217
STL namespace.
virtual void On_disable()
Device disable event handler.
Definition: device.h:224
Generic callback which can be used to define and create an instance of an abstract callable operation...
std::shared_ptr< Request_worker > Ptr
Pointer type.
Definition: request_worker.h:25
Definition: property.h:19
Helper class for proxying callback invocation.
Definition: callback.h:691
Definition: device.h:86
Definition: device.h:103
std::shared_ptr< Vsm_command > Ptr
Pointer type.
Definition: device.h:27
std::shared_ptr< Device > Ptr
Pointer type.
Definition: device.h:105
Definition: device.h:25
std::shared_ptr< Request_context > Ptr
Pointer type.
Definition: request_context.h:25
#define DEFINE_COMMON_CLASS(__class_name,...)
Use this macro to define some common attributes for a class.
Definition: utils.h:25
#define VSM_EXCEPTION(__exc_class, __msg,...)
Throw VSM exception instance.
Definition: exception.h:170
Convenience types for all specific vehicle requests.
std::shared_ptr< Ucs_request > Ptr
Pointer type.
Definition: device.h:88
Definition: device.h:277
Base class for all VSM exceptions.
Definition: exception.h:23