messageManager.h
1 #pragma once
2 
3 #include <iostream>
4 #include <stdio.h>
5 #include <queue>
6 #include <list>
7 #include <boost/thread.hpp>
8 #include <boost/any.hpp>
9 #include <boost/asio.hpp>
10 #include <boost/bind.hpp>
11 #include <boost/enable_shared_from_this.hpp>
12 #include <boost/chrono.hpp>
13 #include <boost/asio/waitable_timer_service.hpp>
14 
15 #ifdef TESTING
16 #include "gtest/gtest.h"
17 #endif
18 
19 typedef boost::asio::basic_waitable_timer<boost::chrono::steady_clock> steady_timer;
20 
26 class Message
27 {
28 public:
29  std::string content;
30  int timeout;
31  int retries;
32  std::string expectedInitResponse;
33  std::string expectedEndResponse;
34  std::string receivedResponse="";
35  Message(std::string content="", int timeout = 100, int retries = 3, std::string expectedInitResponse = "", std::string expectedEndResponse="");
36 };
37 
45 {
46 public:
47  std::string id;
48  std::list<Message> messages;
49  int intervalMessage=0;
50 
58  explicit Transaction(std::list<Message> list):messages(list) {}
63  explicit Transaction(std::initializer_list<Message> list): messages(list){}
64 };
65 
66 enum Status
67 {
68  IDLE,
69  SENDING
70 };
71 
78 {
79 public:
84  virtual std::list<std::string> getUnsolicitedInfoCodes(){
85  std::list<std::string> list;
86  return list;
87  }
88 
94  virtual void transactionProcessed(boost::system::error_code error_code, Transaction transaction) = 0;
95 
100  virtual void unsolicitedInfo(const std::string& message) = 0;
101 
106  {
107  }
108 };
109 
117 class MessageManager: public boost::enable_shared_from_this<MessageManager>
118 {
119 public:
120  explicit MessageManager();
121  virtual ~MessageManager();
122  static std::string stringToHex(const std::string& input, bool printAsciiChar);
123 
124  boost::system::error_code subscribe(MessageManagerObserver* observer);
125  boost::system::error_code unsubscribe(MessageManagerObserver* observer);
126  boost::system::error_code sendAsync(const Transaction& transaction);
127 
132  virtual bool rebootCommunications() = 0;
133 #ifdef TESTING
134  virtual boost::system::error_code sendSync(Transaction& transaction);
135 #else
136  boost::system::error_code sendSync(Transaction& transaction);
137 
138 #endif
139 
140 protected:
141  boost::asio::io_service mIo;
142 
148  virtual boost::system::error_code send(std::string message) = 0;
149 
155  void receivedMessage(const char* data, size_t size);
156  virtual boost::system::error_code receiveUntil(int timeout, std::string& receivedResponse);
157 
158 private:
159  boost::thread bt;
160  std::vector<boost::shared_ptr<boost::thread>> mTransactionThreads;
161  steady_timer m_processQueueTimer;
162  std::list<Transaction> mQueue;
163  Status mStatus;
164  std::vector<MessageManagerObserver*> m_observersList;
165  int mCounter = 0;
166  std::string mDataReceived;
167  std::string mResponse;
168  int mConsecutiveErrors = 0;
169  bool mWaiting;
170  bool mWorking;
171  Message mLastMessageSent;
172  std::mutex mMuxCV, mMuxStatus, mMuxQueue;
173  std::condition_variable mConditionVar;
174  Status getStatus();
175  void setStatus(Status status);
176  void processQueue(const boost::system::error_code& ec);
177  void processTransactions(std::list<Transaction>& queue);
178  void processMessages(boost::system::error_code& ec, std::list<Message>& messages, int interval=0);
179  void processSingleTransaction(boost::system::error_code& ec, Transaction transaction);
180  boost::system::error_code sendAndReceive(Message& message);
181 
182 #ifdef TESTING
183 public:
184  FRIEND_TEST(MessageManager_test, Send_ASyncNoRetries);
185  FRIEND_TEST(MessageManager_test, Send_ASyncRetries);
186  FRIEND_TEST(MessageManager_test, Send_ReceiveOK);
187  FRIEND_TEST(MessageManager_test, Send_ReceiveKO);
188  FRIEND_TEST(MessageManager_test, UnsolicitedInfoIdle);
189  FRIEND_TEST(MessageManager_test, UnsolicitedInfoBusy);
190  FRIEND_TEST(MessageManager_test, receiveUntilTimeoutExpired);
191  FRIEND_TEST(MessageManager_test, ReceiveMessageNoInitNoEnd);
192  FRIEND_TEST(MessageManager_test, ReceiveMessageInitNoEnd);
193  FRIEND_TEST(MessageManager_test, ReceiveMessageInitNoEndError);
194  FRIEND_TEST(MessageManager_test, ReceiveMessageInitNoEndDoubleMessage);
195  FRIEND_TEST(MessageManager_test, ReceiveMessageNoInitEndCorrectly);
196  FRIEND_TEST(MessageManager_test, ReceiveMessageInitEndCorrectly);
197  FRIEND_TEST(MessageManager_test, ReceiveMessageInitEndDoubleMsg);
198  FRIEND_TEST(MessageManager_test, BrokenUnsolicitedInfoMsg);
199  FRIEND_TEST(MessageManager_test, BrokenRequestMsg);
200  FRIEND_TEST(MessageManager_test, CoupledMsg_RequestUnsolicited);
201  FRIEND_TEST(MessageManager_test, CoupledMsg_UnsolicitedRequest);
202  FRIEND_TEST(MessageManager_test, CoupledMsg_RequestRequest);
203  FRIEND_TEST(MessageManager_test, IncompleteUnsolicitedMsg);
204  FRIEND_TEST(MessageManager_test, IncompleteRequestMsg);
205  FRIEND_TEST(MessageManager_test, UnsolicitedMsgWhile_RequestInitAndEndMsg);
206  FRIEND_TEST(MessageManager_test, UnsolicitedMsgWhile_RequestInit);
207  FRIEND_TEST(MessageManager_test, UnsolicitedMsgWhile_RequestEnd);
208  FRIEND_TEST(MessageManager_test, UnsolicitedMsgWhile_RequestNoInitNoEnd);
209 #endif
210 };
virtual std::list< std::string > getUnsolicitedInfoCodes()
Definition: messageManager.h:84
struct to keep a message from a sender
Definition: defTypes.h:24
Class to define the message object.
Definition: messageManager.h:26
Transaction()
Default constructor.
Definition: messageManager.h:53
int timeout
Timeout interval that the application will wait before considering the command sent as failed defined...
Definition: messageManager.h:30
Manages the status file.
Definition: status.h:44
std::string content
Command to send via serial , which may be transformed depending on the protocol.
Definition: messageManager.h:29
std::string expectedInitResponse
Expected init of the response.
Definition: messageManager.h:32
Transaction(std::list< Message > list)
Constructor using list.
Definition: messageManager.h:58
Message Manager observer class.
Definition: messageManager.h:77
boost::asio::basic_waitable_timer< boost::chrono::steady_clock > steady_timer
Typedef to use a steady timer.
Definition: dpyMwClient.h:52
boost::asio::io_service mIo
Boost asio input output service.
Definition: messageManager.h:141
std::string receivedResponse
Received response.
Definition: messageManager.h:34
std::list< Message > messages
List of messages.
Definition: messageManager.h:48
int retries
Number of times that the application will try to send the command after a timeout or a response diffe...
Definition: messageManager.h:31
std::string id
Transaction id.
Definition: messageManager.h:47
Class to define the transaction object.
Definition: messageManager.h:44
Transaction(std::initializer_list< Message > list)
Constructor using initializer list.
Definition: messageManager.h:63
Definition: otaupdaterApi.h:41
virtual ~MessageManagerObserver()
Destructor.
Definition: messageManager.h:105
std::string expectedEndResponse
Expected end of the response.
Definition: messageManager.h:33
Class which manages the logic relative to send/receive messages. This class implements all the logic ...
Definition: messageManager.h:117