message_manager.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011, Southwest Research Institute
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  * * Neither the name of the Southwest Research Institute, nor the names
16  * of its contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 #ifndef FLATHEADERS
35 #else
36 #include "message_manager.h"
37 #include "log_wrapper.h"
38 #include "simple_message.h"
39 #endif
40 
41 #ifdef ROS
42 #include "ros/ros.h"
43 #else
44 #include "unistd.h"
45 #endif
46 
47 using namespace industrial::smpl_msg_connection;
48 using namespace industrial::message_handler;
49 using namespace industrial::simple_message;
50 using namespace industrial::comms_fault_handler;
52 
53 namespace industrial
54 {
55 namespace message_manager
56 {
57 
61 MessageManager::MessageManager()
62 {
63  this->num_handlers_ = 0;
64  for (unsigned int i = 0; i < this->getMaxNumHandlers(); i++)
65  {
66  this->handlers_[i] = NULL;
67  }
68  this->comms_hndlr_ = NULL;
69 }
70 
71 MessageManager::~MessageManager()
72 {
73 
74 }
75 
76 bool MessageManager::init(SmplMsgConnection* connection)
77 {
78  bool rtn = false;
79 
80  LOG_INFO("Initializing message manager with default comms fault handler");
81 
82 
83  if (NULL != connection)
84  {
85  this->getDefaultCommsFaultHandler().init(connection);
86  this->init(connection, (CommsFaultHandler*)(&this->getDefaultCommsFaultHandler()));
87  rtn = true;
88  }
89  else
90  {
91  LOG_ERROR("NULL connection passed into manager init");
92  rtn = false;
93  }
94 
95  return rtn;
96 }
97 
98 bool MessageManager::init(SmplMsgConnection* connection, CommsFaultHandler* fault_handler)
99 {
100  bool rtn = false;
101 
102  LOG_INFO("Initializing message manager");
103 
104  if (NULL != connection && NULL != fault_handler)
105  {
106  this->setConnection(connection);
107  this->getPingHandler().init(connection);
108  this->setCommsFaultHandler(fault_handler);
109 
110  if (this->add(&this->getPingHandler()))
111  {
112  rtn = true;
113  }
114  else
115  {
116  rtn = false;
117  LOG_WARN("Failed to add ping handler, manager won't respond to pings");
118  }
119 
120  }
121  else
122  {
123  LOG_ERROR("NULL connection or NULL fault handler passed into manager init");
124  rtn = false;
125  }
126 
127  return rtn;
128  }
129 
130 
131 
132 void MessageManager::spinOnce()
133 {
134  SimpleMessage msg;
135  MessageHandler* handler = NULL;
136 
137  if(!this->getConnection()->isConnected())
138  {
139  this->getCommsFaultHandler()->connectionFailCB();
140  }
141 
142  if (this->getConnection()->receiveMsg(msg))
143  {
144  LOG_COMM("Message received");
145  handler = this->getHandler(msg.getMessageType());
146 
147  if (NULL != handler)
148  {
149  LOG_DEBUG("Executing handler callback for message type: %d", handler->getMsgType());
150  handler->callback(msg);
151  }
152  else
153  {
155  {
158  this->getConnection()->sendMsg(fail);
159  LOG_WARN("Unhandled message type encounters, sending failure reply");
160  }
161  LOG_ERROR("Message callback for message type: %d, not executed", msg.getMessageType());
162  }
163  }
164  else
165  {
166  LOG_ERROR("Failed to receive incoming message");
167  this->getCommsFaultHandler()->sendFailCB();
168  }
169 }
170 
172 void mySleep(int sec)
173 {
174 #ifdef MOTOPLUS
175  if (ms_per_clock <= 0)
176  ms_per_clock = mpGetRtc();
177 
178  mpTaskDelay(sec * 1000 / ms_per_clock);
179 #else
180  sleep(sec);
181 #endif
182 }
183 
184 void MessageManager::spin()
185 {
186  LOG_INFO("Entering message manager spin loop");
187 #ifdef ROS
188  while (ros::ok())
189 #else
190  while (true)
191 #endif
192  {
193  this->spinOnce();
194 
195  // Throttle loop speed if waiting for a re-connection
196  if (!this->getConnection()->isConnected())
197  mySleep(5);
198  }
199 }
200 
201 bool MessageManager::add(MessageHandler * handler, bool allow_replace)
202 {
203  int idx = -1;
204  bool rtn = false;
205 
206  if (NULL != handler)
207  {
208  // If get handler returns -1 then a hander for the message type
209  // does not exist, and a new one should be added
210  idx = getHandlerIdx(handler->getMsgType());
211  if (0 > idx)
212  {
213  if (this->getMaxNumHandlers() > this->getNumHandlers())
214  {
215  this->handlers_[this->getNumHandlers()] = handler;
216  this->setNumHandlers(this->getNumHandlers() + 1);
217  LOG_INFO("Added message handler for message type: %d", handler->getMsgType());
218  rtn = true;
219  }
220  else
221  {
222  LOG_ERROR("Max number of handlers exceeded");
223  rtn = false;
224  }
225  }
226  else if (allow_replace)
227  {
228  this->handlers_[idx] = handler;
229  }
230  else
231  {
232  LOG_ERROR("Failed to add handler for: %d, handler already exists", handler->getMsgType());
233  rtn = false;
234  }
235  }
236  else
237  {
238  LOG_ERROR("NULL handler not added");
239  rtn = false;
240  }
241  return rtn;
242 }
243 
244 MessageHandler* MessageManager::getHandler(int msg_type)
245 {
246  int idx = getHandlerIdx(msg_type);
247 
248  if (idx < 0)
249  return NULL;
250  else
251  return this->handlers_[idx];
252 }
253 
254 int MessageManager::getHandlerIdx(int msg_type)
255 {
256  int rtn = -1;
257  MessageHandler* temp = NULL;
258 
259  for (unsigned int i = 0; i < this->getMaxNumHandlers(); i++)
260  {
261  temp = this->handlers_[i];
262  if (NULL == temp) break; // end of handler-list
263 
264  if (temp->getMsgType() == msg_type)
265  {
266  rtn = i;
267  break;
268  }
269  }
270 
271  return rtn;
272 }
273 
274 } // namespace message_manager
275 } // namespace industrial
Interface definition for communications fault handler. Defines the type of communcations faults that ...
void init(const M_string &remappings)
Interface definition for message handlers. The interface defines the callback function that should ex...
Defines an interface and common methods for sending simple messages (see simple_message). This interface makes a bare minimum of assumptions:
#define LOG_WARN(format,...)
Definition: log_wrapper.h:107
bool callback(industrial::simple_message::SimpleMessage &in)
Callback function that should be executed when a message arrives DO NOT OVERRIDE THIS FUNCTION...
This class defines a simple messaging protocol for communicating with an industrial robot controller...
#define LOG_COMM(format,...)
Definition: log_wrapper.h:104
int getMessageType()
Gets message type(see StandardMsgType)
#define LOG_ERROR(format,...)
Definition: log_wrapper.h:108
#define LOG_INFO(format,...)
Definition: log_wrapper.h:106
int getMsgType()
Gets message type that callback expects.
ROSCPP_DECL bool ok()
#define LOG_DEBUG(format,...)
Definition: log_wrapper.h:105
bool init(int msgType, int commType, int replyCode, industrial::byte_array::ByteArray &data)
Initializes a fully populated simple message.
ROSCPP_DECL void spinOnce()
int getCommType()
Gets message type(see CommType)


simple_message
Author(s): Shaun Edwards
autogenerated on Sat Sep 21 2019 03:30:09