OpcUaCanOpen
CANopen OPC-UA server
SockCanScan.cpp
Go to the documentation of this file.
1 /*
2  * SockCanScan.cpp
3  *
4  * Created on: Jul 21, 2011
5  * Author: vfilimon
6  */
7 
8 
9 //#include "STCANServer.h"
10 #include "SockCanScan.h"
11 
13 // Construction/Destruction
14 
15 #include <time.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <sys/time.h>
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <sys/ioctl.h>
22 #include <sys/uio.h>
23 #include <net/if.h>
24 
25 #include <linux/can.h>
26 #include <linux/can/raw.h>
27 
29  {
30  CCanAccess *cc;
31  cc = new CSockCanScan();
32  printf("CSockCanScan\n");
33  return cc;
34  }
35 
36 void* CSockCanScan::CanScanControlThread(void *pCanScan)
37 {
38  canMessage cmsg;
39  struct can_frame sockmsg;
40  CSockCanScan *ppcs = reinterpret_cast<CSockCanScan *>(pCanScan);
41  ppcs->run_can = true;
42  int sock = ppcs->sock;
43 // struct msghdr msg;
44  unsigned int nbytes;
45  printf("Start Sock Component\n");
46  while (ppcs->run_can) {
47 
48  /* these settings may be modified by recvmsg() */
49  nbytes = read(sock, &sockmsg, sizeof(struct can_frame));
50 
51  if (nbytes < 0) {
52 // perror("read");
53  continue;
54  }
55 
56  if (nbytes < sizeof(struct can_frame)) {
57 // printf("read: incomplete CAN frame\n");
58  continue;
59  }
60  cmsg.c_id = sockmsg.can_id;
61  cmsg.c_time= time(NULL);
62  cmsg.c_dlc = sockmsg.can_dlc;
63  memcpy(&cmsg.c_data[0],&sockmsg.data[0],8);
64  ppcs->cb->FireOnChange(sock, &cmsg);
65  }
66 
67  pthread_exit(NULL);
68  return NULL;
69 }
70 
71 int CSockCanScan::FinalConstruct(const char *name, const char *parameters,CCanCallback *callb)
72 {
73  cb = callb;
74  run_can = true;
76 
77  if ((sock = configureCanboard(name,parameters)) < 0)
78  return false;
80  pthread_create(&m_hCanScanThread,NULL,&CanScanControlThread,
81  (void *)this);
82 
83  return (!m_idCanScanThread);
84 }
85 
87 {
88  run_can = false;
89 // close socket
90 }
91 
92 int CSockCanScan::configureCanboard(const char *name,const char *parameters)
93 {
94  const char *com;
95 
96  unsigned int tseg1 = 0;
97  unsigned int tseg2 = 0;
98  unsigned int sjw = 0;
99  unsigned int noSamp = 0;
100  unsigned int syncmode = 0;
101  struct sockaddr_can addr;
102 // struct can_frame frame;
103 // int nbytes, i;
104  struct ifreq ifr;
105 
106  int delta,numPar,br;
107 
108 
109 // tUcanInitCanParam InitParam;
110 
111  com = strchr(name,':');
112  if (com == NULL) {
113  com = name;
114  }
115  else {
116  delta = com - name;
117  com++;
118  }
119  printf("Device %s %s\n",name,com);
120  if (parameters)
121  numPar = sscanf(parameters,"%d %d %d %d %d %d",&br,&tseg1,&tseg2,&sjw,&noSamp,&syncmode);
122 
123 // ATLTRACE("BaudRate = %d %s %s %d\n",br,name,com,numPar);
124 // ATLTRACE("Parameters = %d %d %d %d %d %d\n",br,tseg1,tseg2,sjw,noSamp,syncmode);
125 
126  /* Set baud rate to 125 Kbits/second. */
127 
128  sock = socket(PF_CAN, SOCK_RAW, CAN_RAW);
129  if (sock < 0) {
130  // fill out initialisation struct
131  perror("Cannot open the socket");
132  return 0;
133  }
134  memset(&ifr.ifr_name, 0, sizeof(ifr.ifr_name));
135  strncpy(ifr.ifr_name, com, sizeof(com));
136 
137  if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) {
138  perror("SIOCGIFINDEX");
139  return 0;
140  }
141 
142  addr.can_family = AF_CAN;
143  addr.can_ifindex = ifr.ifr_ifindex;
144 
145  if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
146  perror("bind");
147  return 0;
148  }
149 
150  // initialize CAN interface
151 
152  return sock;
153 }
154 
156 {
157  /*
158  time_t ftTimeStamp;
159 
160  time(&ftTimeStamp);
161  cb->FireOnError(numCanHandle, status, &ftTimeStamp );
162 */
163  return status;
164 }
165 
166 bool CSockCanScan::sendMessage(short cobID, unsigned char len, unsigned char *message)
167 {
168  struct can_frame frame;
169  short Status = 0;
170  unsigned int nbytes;
171  unsigned char *buf = message;
172  frame.can_id = cobID;
173  frame.can_dlc = len;
174  int l, l1;
175  l = len;
176  printf("Send Message %d %d\n",cobID,len);
177  do {
178  if (l > 8) {
179  l1 = 8; l = l - 8;
180  }
181  else l1 = l;
182  frame.can_dlc = l1;
183  memcpy(frame.data,buf,l1);
184 
185  nbytes = write(sock, &frame, sizeof(struct can_frame));
186  if (nbytes <sizeof(struct can_frame)) {
187  return sendErrorCode(-1);
188  }
189  buf = buf + l1;
190  }
191  while (l > 8);
192  return sendErrorCode(Status);
193 }
194 
195 bool CSockCanScan::sendRemoteRequest(short cobID)
196 {
197  struct can_frame frame;
198  int nbytes;
199  frame.can_id = cobID + CAN_RTR_FLAG ;
200  frame.can_dlc = 0;
201 printf("Remote Request %d\n",cobID);
202  nbytes = write(sock, &frame, sizeof(struct can_frame));
203  return sendErrorCode(nbytes);
204 }
205 
206 bool CSockCanScan::createBUS(const char *name ,const char *parameters ,CCanCallback *callback)
207 {
208  if (FinalConstruct((const char *)name,parameters,callback) == true) {
209  return true;
210  }
211  else {
212  return false;
213  }
214 }
215