MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
rtai_in_drive.cc
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/mbdyn/base/rtai_in_drive.cc,v 1.45 2017/01/12 14:46:10 masarati Exp $ */
2 /*
3  * MBDyn (C) is a multibody analysis code.
4  * http://www.mbdyn.org
5  *
6  * Copyright (C) 1996-2017
7  *
8  * Pierangelo Masarati <masarati@aero.polimi.it>
9  * Paolo Mantegazza <mantegazza@aero.polimi.it>
10  *
11  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
12  * via La Masa, 34 - 20156 Milano, Italy
13  * http://www.aero.polimi.it
14  *
15  * Changing this copyright notice is forbidden.
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation (version 2 of the License).
20  *
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */
31 
32 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
33 
34 #include <netdb.h>
35 
36 #include "dataman.h"
37 #include "rtai_in_drive.h"
38 #include "mbrtai_utils.h"
39 
41  const DriveHandler* pDH,
42  const std::string& sFileName,
43  const std::string& host,
44  integer nd, const std::vector<doublereal>& v0,
46  bool c, unsigned long /*int*/ n,
47  bool bNonBlocking)
48 : StreamDrive(uL, pDH, sFileName, nd, v0, c, pMod),
49 host(host), node(n), port(-1), bNonBlocking(bNonBlocking),
50 mbx(NULL)
51 {
52  ASSERT(!sFileName.empty());
53 
54  if (create) {
55  ASSERT(node == 0);
56 
57  if (rtmbdyn_rt_mbx_init(sFileName.c_str(), size, &mbx)) {
58  silent_cerr("RTMBDyn mailbox(" << sFileName << ") "
59  "init failed" << std::endl);
61  }
62 
63  } else {
64  if (node) {
65  /* get port ... */
66  port = rtmbdyn_rt_request_port(node);
67  /* FIXME: what in case of failure? */
68  }
69 
70  if (rtmbdyn_RT_get_adr(node, port, sFileName.c_str(), &mbx)) {
71  silent_cerr("RTMBDyn mailbox(" << sFileName << ") "
72  "get_adr failed" << std::endl);
74  }
75  }
76 
77  if (bNonBlocking) {
78  f_receive = rtmbdyn_RT_mbx_receive_if;
79 
80  } else {
81  f_receive = rtmbdyn_RT_mbx_receive;
82  }
83 }
84 
86 {
87  /*
88  * destroy mailbox and so on
89  */
90  if (mbx) {
91  rtmbdyn_rt_mbx_delete(&mbx);
92  }
93 }
94 
95 void
97 {
98  /*
99  * store in pdVal the values of all the channels
100  * served by the mailbox
101  */
102  int rc = f_receive(node, port, mbx, (void *)&buf[0], size);
103  if (!rc) {
104  doublereal *rbuf = (doublereal *)&buf[0] - 1;
105  for (int i = 1; i <= iNumDrives; i++) {
106  pdVal[i] = rbuf[i];
107  }
108 
109  } else {
110  /* FIXME: error */
111  }
112 }
113 
114 /* Scrive il contributo del DriveCaller al file di restart */
115 std::ostream&
116 RTMBDynInDrive::Restart(std::ostream& out) const
117 {
118  return out << "0. /* RTMBDynInDrive not implemented yet */" << std::endl;
119 }
120 
121 Drive *
122 ReadRTMBDynInDrive(const DataManager *pDM, MBDynParser& HP, unsigned int uLabel)
123 {
124  unsigned long node = (unsigned long)-1;
125  std::string host;
126  std::string name;
127  bool create = false;
128 
129  if (HP.IsKeyWord("stream" "drive" "name")) {
130  const char *m = HP.GetStringWithDelims();
131  if (m == NULL) {
132  silent_cerr("RTMBDynInDrive(" << uLabel << "): "
133  "unable to read mailbox name "
134  "at line " << HP.GetLineData() << std::endl);
136 
137  } else if (strlen(m) != 6) {
138  silent_cerr("RTMBDynInDrive(" << uLabel << "): "
139  "illegal mailbox name \"" << m << "\" "
140  "(must be exactly 6 chars) "
141  "at line " << HP.GetLineData() << std::endl);
143  }
144 
145  name = m;
146 
147  } else {
148  silent_cerr("RTMBDynInDrive(" << uLabel << "): "
149  "missing mailbox name "
150  "at line " << HP.GetLineData() << std::endl);
152  }
153 
154  if (HP.IsKeyWord("create")) {
155  if (!HP.GetYesNo(create)) {
156  silent_cerr("RTMBDynInDrive(" << uLabel << "): "
157  "\"create\" must be \"yes\" or \"no\" "
158  "at line " << HP.GetLineData() << std::endl);
160  }
161  }
162 
163  if (HP.IsKeyWord("non" "blocking")) {
164  silent_cout("RTMBDynInDrive(" << uLabel << "): "
165  "RTMBDyn mailboxes are always non-blocking"
166  << std::endl);
167  }
168 
169  if (HP.IsKeyWord("local") || HP.IsKeyWord("path")) {
170  const char *m = HP.GetStringWithDelims();
171 
172  silent_cout("RTMBDynInDrive(" << uLabel << "): "
173  "local path \"" << m << "\" silently ignored"
174  << std::endl);
175  }
176 
177  if (HP.IsKeyWord("port")){
178  int p = HP.GetInt();
179 
180  silent_cout("RTMBDynInDrive(" << uLabel << "): "
181  "port " << p << " silently ignored" << std::endl);
182  }
183 
184  if (HP.IsKeyWord("host")) {
185  const char *h;
186 
187  h = HP.GetStringWithDelims();
188  if (h == NULL) {
189  silent_cerr("RTMBDynInDrive(" << uLabel << "): "
190  "unable to read host "
191  "at line " << HP.GetLineData() << std::endl);
193  }
194 
195  if (create) {
196  silent_cout("RTMBDynInDrive(" << uLabel << "): "
197  "host name \"" << h << "\" silently ignored"
198  << std::endl);
199  } else {
200  host = h;
201 
202  // resolve host
203  // TODO: add support for getnameinfo()
204 #if defined(HAVE_GETADDRINFO)
205  struct addrinfo hints = { 0 }, *res = NULL;
206  int rc;
207 
208  hints.ai_family = AF_INET;
209  hints.ai_socktype = SOCK_STREAM; // FIXME: SOCK_DGRAM?
210  rc = getaddrinfo(host.c_str(), NULL, &hints, &res);
211  if (rc == 0) {
212  node = ((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr;
213  freeaddrinfo(res);
214  }
215 #elif defined(HAVE_GETHOSTBYNAME)
216  // FIXME: non-reentrant
217  struct hostent *he = gethostbyname(host.c_str());
218  if (he != NULL)
219  {
220  node = ((unsigned long *)he->h_addr_list[0])[0];
221  }
222 #elif defined(HAVE_INET_ATON)
223  struct in_addr addr;
224  if (inet_aton(host.c_str(), &addr)) {
225  node = addr.s_addr;
226  }
227 #else // ! HAVE_GETADDRINFO && ! HAVE_GETHOSTBYNAME && ! HAVE_INET_ATON
228  silent_cerr("RTMBDynInDrive(" << uLabel << "): "
229  "host (RTAI RPC) not supported "
230  "at line " << HP.GetLineData() << std::endl);
232 #endif // ! HAVE_GETADDRINFO && ! HAVE_GETHOSTBYNAME && ! HAVE_INET_ATON
233 
234  if (node == (unsigned long)-1) {
235  silent_cerr("RTMBDynInDrive(" << uLabel << "): "
236  "unable to convert host \"" << host << "\" to node" << std::endl);
237  throw ErrGeneric(MBDYN_EXCEPT_ARGS);
238  }
239  }
240  }
241 
242  bool bNonBlocking(true);
243  while (HP.IsArg()) {
244  if (HP.IsKeyWord("signal")) {
245  // ignore
246 
247  } else if (HP.IsKeyWord("no" "signal")) {
248  // ignore
249 
250  } else if (HP.IsKeyWord("blocking")) {
251  bNonBlocking = false;
252 
253  } else if (HP.IsKeyWord("non" "blocking")) {
254  bNonBlocking = true;
255 
256  } else {
257  break;
258  }
259  }
260 
261  int idrives = HP.GetInt();
262  if (idrives <= 0) {
263  silent_cerr("RTMBDynInDrive(" << uLabel << "): "
264  "illegal number of channels "
265  "at line " << HP.GetLineData() << std::endl);
267  }
268 
269  std::vector<doublereal> v0;
270  if (HP.IsKeyWord("initial" "values")) {
271  v0.resize(idrives);
272  for (int i = 0; i < idrives; i++) {
273  v0[i] = HP.GetReal();
274  }
275  }
276 
277  StreamDrive::Modifier *pMod(0);
278  if (HP.IsKeyWord("modifier")) {
279  pMod = ReadStreamDriveModifier(HP, idrives);
280  }
281 
282  Drive* pDr = NULL;
284  RTMBDynInDrive(uLabel,
285  pDM->pGetDrvHdl(),
286  name, host, idrives, v0, pMod,
287  create, node, bNonBlocking));
288 
289  return pDr;
290 }
291 
#define MBDYN_EXCEPT_ARGS
Definition: except.h:63
virtual integer GetInt(integer iDefval=0)
Definition: parser.cc:1050
Definition: drive.h:89
std::vector< char > buf
Definition: streamdrive.h:65
StreamDrive::Modifier * ReadStreamDriveModifier(MBDynParser &HP, integer nDrives)
Definition: streamdrive.cc:169
RTMBDynInDrive(unsigned int uL, const DriveHandler *pDH, const std::string &sFileName, const std::string &host, integer nd, const std::vector< doublereal > &v0, StreamDrive::Modifier *pMod, bool c, unsigned longn, bool bNonBlocking)
const DriveHandler * pGetDrvHdl(void) const
Definition: dataman.h:340
integer iNumDrives
Definition: filedrv.h:47
int(* f_receive)(unsigned long node, int port, void *mbx, void *msg, int msg_size)
Definition: rtai_in_drive.h:54
virtual std::ostream & Restart(std::ostream &out) const
doublereal * pdVal
Definition: filedrv.h:48
unsigned long node
Definition: rtai_in_drive.h:48
virtual bool IsKeyWord(const char *sKeyWord)
Definition: parser.cc:910
const char * host
Definition: autopilot.c:142
virtual const char * GetStringWithDelims(enum Delims Del=DEFAULTDELIM, bool escape=true)
Definition: parser.cc:1228
virtual ~RTMBDynInDrive(void)
#define ASSERT(expression)
Definition: colamd.c:977
#define SAFENEWWITHCONSTRUCTOR(pnt, item, constructor)
Definition: mynewmem.h:698
Drive * ReadRTMBDynInDrive(const DataManager *pDM, MBDynParser &HP, unsigned int uLabel)
static std::stack< cleanup * > c
Definition: cleanup.cc:59
virtual bool GetYesNo(bool &bRet)
Definition: parser.cc:1022
virtual bool IsArg(void)
Definition: parser.cc:807
virtual void ServePending(const doublereal &t)
static const std::vector< doublereal > v0
Definition: fixedstep.cc:45
unsigned short int port
Definition: autopilot.c:143
double doublereal
Definition: colamd.c:52
long int integer
Definition: colamd.c:51
virtual HighParser::ErrOut GetLineData(void) const
Definition: parsinc.cc:697
virtual doublereal GetReal(const doublereal &dDefval=0.0)
Definition: parser.cc:1056