rllib  1
rlcanopendaemon.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  rlcanopen.cpp - description
3  -------------------
4  begin : Tue March 03 2004
5  copyright : (C) 2004 by Marc Br�tigam, Christian Wilmes, R. Lehrig
6  email : lehrig@t-online.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This library is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
13  * published by the Free Software Foundation *
14  * *
15  ***************************************************************************/
16 #include "rlcanopendaemon.h"
17 
21 void sdo_read(rlCanOpenDaemon *_daemonptr,
22  rlSocket* _socket,
23  IPCMSGSTRUCT* _message){
24  rlCanOpenTypes cifmsg;
25  _daemonptr->daemon_thread.lock();
26  _daemonptr->nodes->sdo_read(_message->boardid,
27  _message->nodeid,
28  _message->objectindex,
29  _message->subindex, cifmsg);
30  _daemonptr->daemon_thread.unlock();
31  *_message = cifmsg.createIpcMsg();
32  _message->msgtype=MSG_SDO_READ; _message->transfertype=MSG_RECEIVE;
33  _socket->write((void*) _message, sizeof(*_message));
34 }
35 
39 void sdo_write(rlCanOpenDaemon *_daemonptr,
40  rlSocket* _socket,
41  IPCMSGSTRUCT* _message){
42  rlCanOpenTypes cifmsg;
43  cifmsg.getIpcMsg(*_message);
44  _daemonptr->daemon_thread.lock();
45  _daemonptr->nodes->sdo_write(_message->boardid,
46  _message->nodeid,
47  _message->objectindex,
48  _message->subindex, cifmsg);
49  _daemonptr->daemon_thread.unlock();
50  *_message = cifmsg.createIpcMsg();
51  _message->msgtype=MSG_SDO_WRITE; _message->transfertype=MSG_RECEIVE;
52  _socket->write((void*) _message, sizeof(*_message));
53 }
54 
58 void pdo_receive(rlCanOpenDaemon *_daemonptr,
59  rlSocket* _socket,
60  IPCMSGSTRUCT* _message){
61  int returnvalue;
62  rlCanOpenTypes cifmsg;
63  cifmsg.getIpcMsg(*_message);
64  _daemonptr->daemon_thread.lock();
65  if (_message->mappingid==-1){
66  returnvalue=_daemonptr->nodes->pdo_receive(_message->boardid,
67  _message->nodeid,
68  _message->pdoid,
69  cifmsg);
70  }
71  else
72  {
73  returnvalue=_daemonptr->nodes->pdo_receive(_message->boardid,
74  _message->nodeid,
75  _message->pdoid,
76  _message->mappingid,
77  cifmsg);
78  }
79  _daemonptr->daemon_thread.unlock();
80  *_message = cifmsg.createIpcMsg();
81  _message->msgtype=MSG_PDO_RECEIVE; _message->transfertype=returnvalue;
82  _socket->write((void*) _message, sizeof(*_message));
83 }
84 
88 void pdo_transmit(rlCanOpenDaemon *_daemonptr,
89  rlSocket* _socket,
90  IPCMSGSTRUCT* _message){
91  int returnvalue;
92  rlCanOpenTypes cifmsg;
93  cifmsg.getIpcMsg(*_message);
94  _daemonptr->daemon_thread.lock();
95  if (_message->mappingid==-1){
96  returnvalue=_daemonptr->nodes->pdo_transmit(_message->boardid,
97  _message->nodeid,
98  _message->pdoid,
99  cifmsg);
100  }
101  else
102  {
103  returnvalue=_daemonptr->nodes->pdo_transmit(_message->boardid,
104  _message->nodeid,
105  _message->pdoid,
106  _message->mappingid,
107  cifmsg);
108  }
109  _daemonptr->daemon_thread.unlock();
110  *_message = cifmsg.createIpcMsg();
111  _message->msgtype=MSG_PDO_TRANSMIT; _message->transfertype=returnvalue;
112  _socket->write((void*) _message, sizeof(*_message));
113 }
114 
118 void nmt_transmit(rlCanOpenDaemon *_daemonptr,
119  rlSocket* _socket,
120  IPCMSGSTRUCT* _message){
121  char returnvalue;
122  _daemonptr->daemon_thread.lock();
123  returnvalue=_daemonptr->nodes->sendNMTCommand(_message->boardid,
124  _message->nodeid,
125  _message->mtext[0]);
126  _daemonptr->daemon_thread.unlock();
127  _message->msgtype=MSG_PDO_TRANSMIT; _message->transfertype=returnvalue;
128  _socket->write((void*) _message, sizeof(*_message));
129 }
130 
134 void restart_board(rlCanOpenDaemon *_daemonptr,
135  rlSocket* _socket,
136  IPCMSGSTRUCT* _message){
137  char returnvalue;
138  _daemonptr->daemon_thread.lock();
139  returnvalue=_daemonptr->nodes->restartBoard(_message->boardid,
140  (int) _message->mtext[0]);
141  _daemonptr->daemon_thread.unlock();
142  _message->msgtype=MSG_PDO_TRANSMIT; _message->transfertype=returnvalue;
143  _socket->write((void*) _message, sizeof(*_message));
144 }
145 
149 void getNodeState(rlCanOpenDaemon *_daemonptr,
150  rlSocket* _socket,
151  IPCMSGSTRUCT* _message){
152  int returnvalue;
153  rlCanOpenTypes cifmsg;
154  cifmsg.getIpcMsg(*_message);
155  _daemonptr->daemon_thread.lock();
156  returnvalue=_daemonptr->nodes->getNodeState(_message->boardid,
157  _message->nodeid,
158  cifmsg);
159  _daemonptr->daemon_thread.unlock();
160  *_message = cifmsg.createIpcMsg();
161  _message->msgtype=MSG_GET_NODE_STATE; _message->transfertype=returnvalue;
162  _socket->write((void*) _message, sizeof(*_message));
163 }
164 
172 static void *clientconnection(void *arg)
173 {
174  //cout<<"\n client connection established...\n";
175 
176  rlCanOpenTypes cifmsg;
177  THREAD_PARAM *p = (THREAD_PARAM *) arg;
179  IPCMSGSTRUCT message;
180  int socketdescr = tr->socketdescr;
181  rlCanOpenDaemon *daemonptr = tr->daemonptr;
182  int ret;
183  rlSocket socket(socketdescr);
184 
185  rlDebugPrintf("client connection established...\n");
186  while(socket.isConnected())
187  {
188  ret = socket.read((void*) &message, sizeof(message));
189  if(ret <= 0) break;
190  if ((message.msgtype==MSG_SDO_READ)&&(message.transfertype==MSG_SEND)){
191  sdo_read(daemonptr, &socket, &message);
192  }
193  if ((message.msgtype==MSG_SDO_WRITE)&&(message.transfertype==MSG_SEND)){
194  sdo_write(daemonptr, &socket, &message);
195  }
196  if ((message.msgtype==MSG_PDO_RECEIVE)&&(message.transfertype==MSG_SEND)){
197  pdo_receive(daemonptr, &socket, &message);
198  }
199  if ((message.msgtype==MSG_PDO_TRANSMIT)&&(message.transfertype==MSG_SEND)){
200  pdo_transmit(daemonptr, &socket, &message);
201  }
202  if ((message.msgtype==MSG_NMT_TRANSMIT)&&(message.transfertype==MSG_SEND)){
203  nmt_transmit(daemonptr, &socket, &message);
204  }
205  if ((message.msgtype==MSG_RESTART_BOARD)&&(message.transfertype==MSG_SEND)){
206  restart_board(daemonptr, &socket, &message);
207  }
208  if ((message.msgtype==MSG_GET_NODE_STATE)&&(message.transfertype==MSG_SEND)){
209  getNodeState(daemonptr, &socket, &message);
210  }
211 
212  }
213  rlDebugPrintf("client disconnect...\n");
214  //cout<<"\n client disconnect...\n";
215  return NULL;
216 }
217 
218 
221 static void *listenerthread(void *arg)
222 {
223 
224  // socketdescriptor;
225  int socketdescr;
226  // parameter struct for accessing function parameters
227  THREAD_PARAM *p = (THREAD_PARAM *) arg;
228  // new parameter struct for passing parameters to handler thread
229  THREADTRANSFER tr;
230  rlCanOpenDaemon *daemonptr = (rlCanOpenDaemon*) p->user;
231  tr.daemonptr = daemonptr;
232  int port = daemonptr->getPort();
233  // wait for connections with accept();
234  rlDebugPrintf("\n starting listener on port %d...\n", port);
235  // initialize socket with daemonport
236  rlSocket s("localhost",port,0);
237  // listener main loop
238  while(1){
239  socketdescr = s.connect();
240  if(socketdescr == -1) break;
241  tr.socketdescr = socketdescr;
242  daemonptr->daemon_thread.create(clientconnection, &tr);
243  // wait for clientconnection to save socketdescriptor
244  rlsleep(100);
245  }
246  rlDebugPrintf("\n killing listener...\n");
247  return NULL;
248 }
249 
250 
251 
254  nodes = new rlCanOpen();
255  port = 5000;
256 }
257 
259 rlCanOpenDaemon::rlCanOpenDaemon(int _port, char* _iniFileName){
260  if (_iniFileName!=0){
261  nodes = new rlCanOpen(_iniFileName);
262  }
263  else{
264  nodes = new rlCanOpen();
265  }
266  port = _port;
267 
268 
269 }
270 
273  rlDebugPrintf("destruktor rlCanOpenDaemon\n");
274  if (nodes!=0){
275  delete nodes;
276  }
277 }
278 
281  return port;
282 }
283 
285 
290  /* NO NO this has to be done by the user RL 17.06.2004
291  while(1){
292  rlsleep(100);
293  }
294  */
295 }
296 
297 
rlThread daemon_thread
int rlDebugPrintf(const char *format,...)
Definition: rlcutil.cpp:61
main class which provides canopen API functions and manages all nodes.
Definition: rlcanopen.h:55
int write(const void *buf, int len)
Definition: rlsocket.cpp:292
the IPCMSGSTRUCT is the transfer buffer which is send trough TCP sockets
canopen tcp/ip interface for concurrent device-access of multiple clientprocesses ...
void * user
Definition: rlthread.h:30
void pdo_receive(rlCanOpenDaemon *_daemonptr, rlSocket *_socket, IPCMSGSTRUCT *_message)
char mtext[247]
void getIpcMsg(IPCMSGSTRUCT _myIpcMsg)
overwrites all data with IPCMSGSTRUCT data
void restart_board(rlCanOpenDaemon *_daemonptr, rlSocket *_socket, IPCMSGSTRUCT *_message)
int unlock()
Definition: rlthread.cpp:52
class to handle CANopen types
void getNodeState(rlCanOpenDaemon *_daemonptr, rlSocket *_socket, IPCMSGSTRUCT *_message)
static void * clientconnection(void *arg)
int sdo_read(int _boardnr, int _nodeid, int _objectindex, int _subindex, rlCanOpenTypes &_sdo_data)
read a certain object from the object dictionary of a node
Definition: rlcanopen.cpp:332
rlCanOpen * nodes
int create(void *(*func)(void *), void *argument)
Definition: rlthread.cpp:35
int sendNMTCommand(int _boardnr, int _nodeid, unsigned char _cmd)
send a NMT Command to one or all nodes (of one board)
Definition: rlcanopen.cpp:1132
void nmt_transmit(rlCanOpenDaemon *_daemonptr, rlSocket *_socket, IPCMSGSTRUCT *_message)
int pdo_transmit(int _boardnr, int _nodeid, int _pdonr, int _mappingnr, rlCanOpenTypes &_pdo_data)
transmit a mapped object within a PDO to a specific node
Definition: rlcanopen.cpp:703
int restartBoard(int _boardnr, int _restarttype)
using this function you are able to restart a CanOpenMaster board
Definition: rlcanopen.cpp:1114
void sdo_read(rlCanOpenDaemon *_daemonptr, rlSocket *_socket, IPCMSGSTRUCT *_message)
int pdo_receive(int _boardnr, int _nodeid, int _pdonr, int _mappingnr, rlCanOpenTypes &_pdo_data)
using the pdo_receive function you can receive a mapped object within PDO
Definition: rlcanopen.cpp:544
static void * listenerthread(void *arg)
int sdo_write(int _boardnr, int _nodeid, int _objectindex, int _subindex, rlCanOpenTypes &_sdo_data)
write data into a certain object from the object dictionary of a node
Definition: rlcanopen.cpp:431
void sdo_write(rlCanOpenDaemon *_daemonptr, rlSocket *_socket, IPCMSGSTRUCT *_message)
rlCanOpenDaemon * daemonptr
void pdo_transmit(rlCanOpenDaemon *_daemonptr, rlSocket *_socket, IPCMSGSTRUCT *_message)
~rlCanOpenDaemon()
destructor destroys rlcanopen object
int getPort()
returns value of current port
void start()
runs service in endless loop
void rlsleep(long msec)
Definition: rlwthread.cpp:396
rlCanOpenDaemon()
empty constructor initializes on port 5000.
IPCMSGSTRUCT createIpcMsg()
returns a IPCMSGSTRUCT filled with current object data
int connect()
Definition: rlsocket.cpp:321
int getNodeState(int _boardnr, int _nodeid, rlCanOpenTypes &_data)
use this function to get information about a specific node
Definition: rlcanopen.cpp:1045
int lock()
Definition: rlthread.cpp:47