VSM C++ SDK
Vehicle Specific Modules SDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
device.h
1 // Copyright (c) 2018, Smart Projects Holdings Ltd
2 // All rights reserved.
3 // See LICENSE file for license details.
4 
5 #ifndef _UGCS_VSM_DEVICE_H_
6 #define _UGCS_VSM_DEVICE_H_
7 
8 #include <ugcs/vsm/property.h>
9 #include <ugcs/vsm/callback.h>
11 #include <ugcs/vsm/optional.h>
12 #include <ugcs/vsm/subsystem.h>
13 
14 #include <memory>
15 #include <unordered_map>
16 #include <unordered_set>
17 
18 namespace ugcs {
19 namespace vsm {
20 
21 typedef std::shared_ptr<ugcs::vsm::proto::Vsm_message> Proto_msg_ptr;
22 
23 class Ucs_request :public Request
24 {
26 
27 public:
28  Ucs_request(ugcs::vsm::proto::Vsm_message);
29 
30  void
31  Complete(
32  ugcs::vsm::proto::Status_code = ugcs::vsm::proto::STATUS_OK,
33  const std::string& description = std::string());
34 
35  // Device can modify device_response of this message
36  Proto_msg_ptr response = nullptr;
37 
38  // Used to send in-progress status for the request.
39  uint32_t stream_id = 0;
40 
41  ugcs::vsm::proto::Vsm_message request;
42 };
43 
44 class Device: public std::enable_shared_from_this<Device>
45 {
46  DEFINE_COMMON_CLASS(Device, Device)
47 
48 public:
49  // Constructor for device with provided processor and completion context.
50  // If processor and completion_ctx are not specified then
51  // Device will create it's own contexts and execute them in separate thread.
52  // If processor and completion_ctx are specified then
53  // Device will use provided contexts and will not create the thread.
54  Device(
55  proto::Device_type type,
56  Request_processor::Ptr processor = nullptr,
57  Request_completion_context::Ptr completion_ctx = nullptr);
58 
59  typedef Callback_proxy<
60  void,
61  std::vector<Property::Ptr>>
63 
65  typedef Callback_proxy<void, uint32_t, Proto_msg_ptr> Response_sender;
66 
67  virtual
68  ~Device();
69 
73  void
74  Enable();
75 
79  void
80  Disable();
81 
83  bool
84  Is_enabled() { return is_enabled;}
85 
87  Device(const Device &) = delete;
88 
92  void
93  On_ucs_message(
94  ugcs::vsm::proto::Vsm_message message,
95  Response_sender completion_handler = Response_sender(),
96  ugcs::vsm::Request_completion_context::Ptr completion_ctx = nullptr);
97 
98  // Used by Cucs_processor only.
99  // Derived class must override.
100  void
101  Register(ugcs::vsm::proto::Vsm_message&);
102 
103  // Create/replace property value. By default type is derived from value.
104  template<typename Type>
106  Set_property(
107  const std::string& name,
108  Type value,
109  proto::Field_semantic semantic = proto::FIELD_SEMANTIC_DEFAULT)
110  {
111  auto it = properties.find(name);
112  if (it == properties.end()) {
113  auto f = Property::Create(name, value, semantic);
114  properties.emplace(name, f);
115  return f;
116  } else {
117  it->second->Set_value(value);
118  return it->second;
119  }
120  }
121 
122  uint32_t
123  Get_session_id();
124 
127  Get_completion_ctx();
128 
129  static void
130  Set_failsafe_actions(Property::Ptr p, std::initializer_list<proto::Failsafe_action> actions);
131 
135  void
136  Register();
137 
139  void
140  Unregister();
141 
143  bool
144  Is_registered();
145 
146  std::string
147  Dump_command(const ugcs::vsm::proto::Device_command &);
148 
150  Add_subsystem(proto::Subsystem_type);
151 
152 protected:
155  Get_processing_ctx();
156 
160  virtual void
162  {};
163 
167  virtual void
169  {};
170 
176  virtual void
177  Handle_ucs_command(
178  Ucs_request::Ptr request);
179 
185  void
186  Report_progress(
187  Ucs_request::Ptr request,
188  float progress = -1.0,
189  const std::string& description = std::string());
190 
191  void
192  Send_ucs_message(Proto_msg_ptr msg);
193 
195  Get_command(int id);
196 
197  // Append to the list of status messages. Commit_to_ucs will push all to ucs.
198  void
199  Add_status_message(const std::string& m);
200 
201  class Commit_scope {
202  public:
203  Commit_scope(Device& d):d(d) {}
204  ~Commit_scope() {d.Commit_to_ucs();}
205  private:
206  Device& d;
207  };
208 
209  // Add this in each scope which requires a call to Commit_to_ucs().
210  // This guarantees the commit on scope leave and you do not need to
211  // add Commit_to_ucs() before each return.
212  #define CREATE_COMMIT_SCOPE auto auto_device_commit_scope = Commit_scope(*this)
213 
214  // Set log_message to true to see what gets sent to the server.
215  void
216  Commit_to_ucs(bool log_message = false);
217 
218  const proto::Device_type device_type;
219 
220  Request_processor::Ptr processor;
221  Request_completion_context::Ptr completion_ctx;
222 
223  std::chrono::time_point<std::chrono::system_clock> begin_of_epoch;
224 
225  std::vector<Subsystem::Ptr> subsystems;
226 
227 private:
228  Request_worker::Ptr worker = nullptr;
229 
230  // Status messages to be sent to ucs.
231  std::list<std::string> device_status_messages;
232 
233  uint32_t my_handle = 0;
234 
236  bool is_enabled = false;
237 
238  std::unordered_map<std::string, Property::Ptr> properties;
239 };
240 
243 #define DEVICE_LOG(level_, vehicle_, fmt_, ...) \
244  _LOG_WRITE_MSG(level_, "[%d] " fmt_, \
245  (vehicle_).Get_session_id(), ## __VA_ARGS__)
246 
249 // @{
250 #define DEVICE_LOG_DBG(vehicle_, fmt_, ...) \
251  DEVICE_LOG(::ugcs::vsm::Log::Level::DEBUGGING, vehicle_, fmt_, ## __VA_ARGS__)
252 
253 #define DEVICE_LOG_INF(vehicle_, fmt_, ...) \
254  DEVICE_LOG(::ugcs::vsm::Log::Level::INFO, vehicle_, fmt_, ## __VA_ARGS__)
255 
256 #define DEVICE_LOG_WRN(vehicle_, fmt_, ...) \
257  DEVICE_LOG(::ugcs::vsm::Log::Level::WARNING, vehicle_, fmt_, ## __VA_ARGS__)
258 
259 #define DEVICE_LOG_ERR(vehicle_, fmt_, ...) \
260  DEVICE_LOG(::ugcs::vsm::Log::Level::ERROR, vehicle_, fmt_, ## __VA_ARGS__)
261 // @}
262 
263 } /* namespace vsm */
264 } /* namespace ugcs */
265 
266 #endif /* _UGCS_VSM_DEVICE_H_ */
static Ptr Create(Args &&...args)
Create an instance.
Definition: property.h:18
Generic request for implementing inter-threads communications and asynchronous operations.
Definition: request_container.h:37
Request worker.
std::shared_ptr< Property > Ptr
Pointer type.
Definition: property.h:18
virtual void On_enable()
Device enable event handler.
Definition: device.h:161
virtual void On_disable()
Device disable event handler.
Definition: device.h:168
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
Request execution context.
Definition: request_context.h:24
Definition: property.h:16
Helper class for proxying callback invocation.
Definition: callback.h:694
Definition: device.h:23
Definition: device.h:44
std::shared_ptr< Vsm_command > Ptr
Pointer type.
Definition: subsystem.h:24
std::shared_ptr< Device > Ptr
Pointer type.
Definition: device.h:46
std::shared_ptr< Request_context > Ptr
Pointer type.
Definition: request_context.h:25
std::shared_ptr< Subsystem > Ptr
Pointer type.
Definition: subsystem.h:84
#define DEFINE_COMMON_CLASS(__class_name,...)
Use this macro to define some common attributes for a class.
Definition: utils.h:25
T value
Stored value (in wire byte order).
Definition: endian.h:356
std::shared_ptr< Ucs_request > Ptr
Pointer type.
Definition: device.h:25
Definition: device.h:201