Communication.cpp
Go to the documentation of this file.
1 /*
2 BSD 2-Clause License
3 
4 Copyright (c) 2019, Simranjeet Singh
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 1. Redistributions of source code must retain the above copyright notice, this
11  list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 
29 #include <ros/ros.h>
30 #include <stdio.h>
31 #include <sys/socket.h>
32 #include <stdlib.h>
33 #include <netinet/in.h>
34 #include <string.h>
35 #include <arpa/inet.h>
36 #include <fcntl.h>
37 #include <sys/ioctl.h>
38 #include <unistd.h>
39 #include <errno.h>
41 #include <eyantra_drone/Protocol.h>
42 
43 
44 using namespace std;
46 int indx=0;
47 unsigned int len = 0;
48 uint8_t checksum=0;
49 uint8_t command=0;
50 uint8_t payload_size=0;
51 
52 int optval;
53 socklen_t optlen = sizeof(optval);
54 
58 uint8_t recbuf[1024];
59 
60 int c_state = IDLE;
61 uint8_t c;
62 bool err_rcvd = false;
63 int offset = 0, dataSize = 0;
64 // uint8_t checksum = 0;
65 uint8_t cmd;
66 //byte[] inBuf = new byte[256];
67 int i = 0;
68 
70  int res;
71  struct sockaddr_in addr;
72  long arg;
73  fd_set myset;
74  struct timeval tv;
75  int valopt;
76  socklen_t lon;
77 
78  cout<<"Connecting to eDrone......\n";
79 
80  // Create socket
81  sockID = socket(AF_INET, SOCK_STREAM, 0);
82  //Check if socket is created. If not, socket() returns -1
83  if (sockID < 0) {
84  // fprintf(stderr, "Error creating socket (%d %s)\n", errno, strerror(errno));
85  cout<<"Cannot connect to DroneNode, please try again1\n";
86  exit(0);
87  }
88 
89  addr.sin_family = AF_INET;
90  addr.sin_port = htons(23);//23 is the PORT to connect to as defined in DroneNode.cpp. Use port 9060 for Drone camera!
91  addr.sin_addr.s_addr = inet_addr("192.168.4.1");//Use 192.168.0.1 for Drone camera!
92 
93  //socket() sets it to blocking
94  // Set to non-blocking. arg will re
95  if( (arg = fcntl(sockID, F_GETFL, NULL)) < 0) {
96  // fprintf(stderr, "Error fcntl(..., F_GETFL) (%s)\n", strerror(errno));
97  cout<<"Cannot connect to Drone, please try again2\n";
98  exit(0);
99  }
100  arg |= O_NONBLOCK;
101  if( fcntl(sockID, F_SETFL, arg) < 0) {
102  // fprintf(stderr, "Error fcntl(..., F_SETFL) (%s)\n", strerror(errno));
103  cout<<"Cannot connect to Drone, please try again3\n";
104  exit(0);
105  }
106 
107  // Trying to connect with timeout
108  res = connect(sockID, (struct sockaddr *)&addr, sizeof(addr));
109  //fprintf(stderr,"socket is ready %d",res);
110  //If res < 0, failure. If res == 0, success.
111  if (res < 0) {
112  if (errno == EINPROGRESS) {
113  //fprintf(stderr, "socket is ready %d ",res);
114  //fprintf(stderr, "EINPROGRESS in connect() - selecting\n");
115  do {
116  tv.tv_sec = 7;
117  tv.tv_usec = 0;
118  FD_ZERO(&myset);
119  FD_SET(sockID, &myset);
120  res = select(sockID+1, NULL, &myset, NULL, &tv);
121  //fprintf(stderr,"socket is ready %d",res);
122  if (res < 0 && errno != EINTR) {
123  //fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));
124  cout<<"Cannot connect to Drone, please try again4\n";
125  exit(0);
126  }
127  else if (res > 0) {
128  // Socket selected for write
129  lon = sizeof(int);
130  if (getsockopt(sockID, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0) {
131  //fprintf(stderr, "Error in getsockopt() %d - %s\n", errno, strerror(errno));
132  cout<<"Cannot connect to Drone, please try again5\n";
133  exit(0);
134  }
135  // Check the value returned...
136  if (valopt) {
137  // fprintf(stderr, "Error in delayed connection() %d - %s\n", valopt, strerror(valopt));
138  cout<<"Cannot connect to Drone, please try again6\n";
139 
140  exit(0);
141  }
142  break;
143  }
144  else {
145  // fprintf(stderr, "Timeout in select() - Cancelling!\n");
146  cout<<"Cannot connect to Drone, please try again7\n";
147  exit(0);
148  }
149  } while (1);
150  }
151  else {
152  //fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));
153  cout<<"Cannot connect to Drone, please try again8\n";
154  exit(0);
155  }
156  }
157 
158  // Set to blocking mode again...
159  if( (arg = fcntl(sockID, F_GETFL, NULL)) < 0) {
160  // fprintf(stderr, "Error fcntl(..., F_GETFL) (%s)\n", strerror(errno));
161  cout<<"Cannot connect to Drone, please try again9\n";
162  exit(0);
163  }
164  arg &= (~O_NONBLOCK);
165  if( fcntl(sockID, F_SETFL, arg) < 0) {
166  // fprintf(stderr, "Error fcntl(..., F_SETFL) (%s)\n", strerror(errno));
167  cout<<"Cannot connect to Drone, please try again0\n";
168  exit(0);
169  }
170  // I hope that is all
171  //printf("Hello message sent\n");
172  /* Check the status for the keepalive option */
173  if(getsockopt(sockID, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0) {
174  // perror("getsockopt()");
175  cout<<"Cannot connect to Drone, please try again11\n";
176  close(sockID);
177  exit(EXIT_FAILURE);
178  }
179  // printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF"));
180  /* Set the option active */
181  optval = 1;
182  optlen = sizeof(optval);
183  if(setsockopt(sockID, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
184  // perror("setsockopt()");
185  cout<<"Cannot connect to Drone, please try again12\n";
186  close(sockID);
187  exit(EXIT_FAILURE);
188  }
189  //printf("SO_KEEPALIVE set on socket\n");
190  /* Check the status again */
191  if(getsockopt(sockID, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0) {
192  // perror("getsockopt()");
193  cout<<"Cannot connect to Drone, please try again13\n";
194  close(sockID);
195  exit(EXIT_FAILURE);
196  }
197  //printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF"));
198 
199  int error = 0;
200  socklen_t len = sizeof (error);
201  int retval = getsockopt (sockID, SOL_SOCKET, SO_ERROR, &error, &len);
202 
203  if (retval != 0) {
204  /* there was a problem getting the error code */
205  // fprintf(stderr, "error getting socket error code: %s\n", strerror(retval));
206  cout<<"Cannot connect to Drone, please try again14\n";
207  exit(EXIT_FAILURE);
208  // return;
209  }
210 
211  if (error != 0) {
212  /* socket has a non zero error status */
213  // fprintf(stderr, "socket error: %s\n", strerror(error));
214  cout<<"Cannot connect to Drone, please try again15\n";
215  exit(EXIT_FAILURE);
216  }else{
217  //fprintf(stderr, "socket is up \n");
218  cout<<"eDrone Connected\n";
219  }
220  return true;
221 }
222 
223 int Communication::writeSock(const void *buf, int count){
224  int k=write(sockID,buf,count);
225  socketSyckLock=1;
226  return k;
227 }
228 
229 uint8_t Communication::readSock(void *buf, int count){
230  int k=read(sockID,buf,count);
231  if(k>0){
232  uint8_t val=recbuf[0];
233  return val;
234  }else{
235  return k;
236  }
237 }
238 
240  c = readSock(recbuf,1);
241  if (c_state == IDLE){
242  c_state = (c == '$') ? HEADER_START : IDLE;
243  }else if (c_state == HEADER_START) {
244  c_state = (c == 'M') ? HEADER_M : IDLE;
245  }else if (c_state == HEADER_M) {
246  if (c == '>') {
248  } else if (c == '!') {
250  } else {
251  c_state = IDLE;
252  }
253  } else if (c_state == HEADER_ARROW || c_state == HEADER_ERR) {
254  /* is this an error message? */
255  err_rcvd = (c_state == HEADER_ERR);
256  /* now we are expecting the payload size */
257  dataSize = (c & 0xFF);
258  /* reset index variables */
259  // p = 0;
260  offset = 0;
261  checksum = 0;
262  checksum ^= (c & 0xFF);
263  /* the command is to follow */
265  }else if (c_state == HEADER_SIZE) {
266  cmd = (uint8_t) (c & 0xFF);
267  //printf("cmd Value= %i\n",cmd );
268  checksum ^= (c & 0xFF);
270  }else if (c_state == HEADER_CMD && offset < dataSize) {
271  checksum ^= (c & 0xFF);
272  inputBuffer[offset++] = (uint8_t) (c & 0xFF);
273  if(cmd==108){
274  // Log.d("#########", "MSP_ATTITUDE: recived payload= "+inBuf[offset-1]);
275  }
276  }else if (c_state == HEADER_CMD && offset >= dataSize) {
277  /* compare calculated and transferred checksum */
278  if ((checksum & 0xFF) == (c & 0xFF)) {
279  if (err_rcvd) {
280  // Log.e("Multiwii protocol",
281  // "Copter did not understand request type " + c);
282  }else {
283 
284  bufferIndex=0;
285  //printf("cmd Value= %i\n",cmd );
286  pro.evaluateCommand(cmd);
287  //SONG BO ---------------------------------------
288  // DataFlow = DATA_FLOW_TIME_OUT;
289  }
290  }else {
291 
292  }
293  c_state = IDLE;
294  }
295 }
296 
297 bool Communication::connectMulSock(const std::string& ip, int index){
298 
299  int res;
300  struct sockaddr_in addr;
301  long arg;
302  fd_set myset;
303  struct timeval tv;
304  int valopt;
305  socklen_t lon;
306 
307  cout<<"Connecting to Drone\n";
308 
309  // Create interface
310  sockIDList[index] = socket(AF_INET, SOCK_STREAM, 0);
311  //Check if socket is created. If not, socket() returns -1
312  if (sockIDList[index] < 0) {
313  // fprintf(stderr, "Error creating socket (%d %s)\n", errno, strerror(errno));
314  cout<<"Cannot connect to Drone, please try again1\n";
315  exit(0);
316  }
317 
318  //address of the server
319  addr.sin_family = AF_INET;
320  addr.sin_port = htons(23);//23 is the PORT to connect to as defined in DroneNode.cpp!
321  addr.sin_addr.s_addr = inet_addr(ip.c_str());
322 
323  //socket() sets it to blocking
324  // Set to non-blocking. arg will re
325  if( (arg = fcntl(sockIDList[index], F_GETFL, NULL)) < 0) {
326  // fprintf(stderr, "Error fcntl(..., F_GETFL) (%s)\n", strerror(errno));
327  cout<<"Cannot connect to Drone, please try again2\n";
328  exit(0);
329  }
330  arg |= O_NONBLOCK;
331  if( fcntl(sockIDList[index], F_SETFL, arg) < 0) {
332  // fprintf(stderr, "Error fcntl(..., F_SETFL) (%s)\n", strerror(errno));
333  cout<<"Cannot connect to Drone, please try again3\n";
334  exit(0);
335  }
336 
337  // Trying to connect with timeout. connect() is blocking
338  res = connect(sockIDList[index], (struct sockaddr *)&addr, sizeof(addr));
339  //fprintf(stderr,"socket is ready %d",res);
340  //If res < 0, failure. If res == 0, success.
341  if (res < 0) {
342  if (errno == EINPROGRESS) {
343  //fprintf(stderr, "socket is ready %d ",res);
344  //fprintf(stderr, "EINPROGRESS in connect() - selecting\n");
345  do {
346  tv.tv_sec = 7;
347  tv.tv_usec = 0;
348  FD_ZERO(&myset);
349  FD_SET(sockIDList[index], &myset);
350  res = select(sockIDList[index]+1, NULL, &myset, NULL, &tv);
351  //fprintf(stderr,"socket is ready %d",res);
352  // cout<<res;
353  if (res < 0 && errno != EINTR) {
354  //fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));
355  cout<<"Cannot connect to Drone, please try again4\n";
356  exit(0);
357  }else if (res > 0) {
358  // Socket selected for write
359  lon = sizeof(int);
360  if (getsockopt(sockIDList[index], SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0) {
361  //fprintf(stderr, "Error in getsockopt() %d - %s\n", errno, strerror(errno));
362  cout<<"Cannot connect to Drone, please try again5\n";
363  exit(0);
364  }
365  // Check the value returned...
366  if (valopt) {
367  // fprintf(stderr, "Error in delayed connection() %d - %s\n", valopt, strerror(valopt));
368  cout<<"Cannot connect to Drone, please try again6\n";
369  exit(0);
370  }
371  break;
372  }else {
373  // fprintf(stderr, "Timeout in select() - Cancelling!\n");
374  cout<<"Cannot connect to Drone, please try again7\n";
375  exit(0);
376  }
377  }while (1);
378  }
379  else {
380  //fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));
381  cout<<"Cannot connect to Drone, please try again8\n";
382  exit(0);
383  }
384  }
385 
386  // Set to blocking mode again...
387  if( (arg = fcntl(sockIDList[index], F_GETFL, NULL)) < 0) {
388  // fprintf(stderr, "Error fcntl(..., F_GETFL) (%s)\n", strerror(errno));
389  cout<<"Cannot connect to Drone, please try again9\n";
390  exit(0);
391  }
392  arg &= (~O_NONBLOCK);
393  if( fcntl(sockIDList[index], F_SETFL, arg) < 0) {
394  // fprintf(stderr, "Error fcntl(..., F_SETFL) (%s)\n", strerror(errno));
395  cout<<"Cannot connect to Drone, please try again10\n";
396  exit(0);
397  }
398 
399  /* Check the status for the keepalive option */
400  if(getsockopt(sockIDList[index], SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0) {
401  // perror("getsockopt()");
402  cout<<"Cannot connect to Drone, please try again11\n";
403  close(sockIDList[index]);
404  exit(EXIT_FAILURE);
405  }
406  // printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF"));
407  /* Set the option active */
408  optval = 1;
409  optlen = sizeof(optval);
410  if(setsockopt(sockIDList[index], SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
411  // perror("setsockopt()");
412  cout<<"Cannot connect to Drone, please try again12\n";
413  close(sockIDList[index]);
414  exit(EXIT_FAILURE);
415  }
416  //printf("SO_KEEPALIVE set on socket\n");
417  /* Check the status again */
418  if(getsockopt(sockIDList[index], SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0) {
419  // perror("getsockopt()");
420  cout<<"Cannot connect to Drone, please try again13\n";
421  close(sockIDList[index]);
422  exit(EXIT_FAILURE);
423  }
424  //printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF"));
425 
426  int error = 0;
427  socklen_t len = sizeof (error);
428  int retval = getsockopt (sockIDList[index], SOL_SOCKET, SO_ERROR, &error, &len);
429 
430  if (retval != 0) {
431  /* there was a problem getting the error code */
432  // fprintf(stderr, "error getting socket error code: %s\n", strerror(retval));
433  cout<<"Cannot connect to Drone, please try again14\n";
434  exit(EXIT_FAILURE);
435  // return;
436  }
437 
438  if (error != 0) {
439  /* socket has a non zero error status */
440  // fprintf(stderr, "socket error: %s\n", strerror(error));
441  cout<<"Cannot connect to Drone, please try again15\n";
442  exit(EXIT_FAILURE);
443  }else{
444  //fprintf(stderr, "socket is up \n");
445  cout<<"Drone Connected\n";
446  }
447  return true;
448 }
449 
450 int Communication::writeMulSock(const void *buf, int count, int i){
451  // while (socketSyckLock) {
452  // /* code */
453  // //printf("value of synclock in write = %i\n",socketSyckLock );
454  // usleep(2);
455  // }
456  //usleep(2000);
457  int k=write(sockIDList[i],buf,count);
458  //socketOpStarted=1;
459  //usleep(500);
460  //readFrame();
461  socketSyckLock=1;
462  return k;
463 }
464 
465 uint8_t Communication::readMulSock(void *buf, int count, int index){
466  int k=read(sockIDList[index],buf,count);
467  if(k>0){
468  uint8_t val=recbuf[0];
469  return val;
470  }else{
471  return k;
472  }
473 }
474 
476  cout<<index;
477  c = readMulSock(recbuf,1,index);
478  // Log.v("READ", "Data: " + c);
479  // printf("read Value= %i\n",c );
480  // c_state = IDLE;
481  // Log.e("MultiwiiProtocol", "Read = null");
482  if (c_state == IDLE){
483  c_state = (c == '$') ? HEADER_START : IDLE;
484  }else if (c_state == HEADER_START) {
485  c_state = (c == 'M') ? HEADER_M : IDLE;
486  }else if (c_state == HEADER_M) {
487  if (c == '>') {
489  } else if (c == '!') {
491  } else {
492  c_state = IDLE;
493  }
494  } else if (c_state == HEADER_ARROW || c_state == HEADER_ERR) {
495  /* is this an error message? */
496  err_rcvd = (c_state == HEADER_ERR);
497  /* now we are expecting the payload size */
498  dataSize = (c & 0xFF);
499  /* reset index variables */
500  // p = 0;
501  offset = 0;
502  checksum = 0;
503  checksum ^= (c & 0xFF);
504  /* the command is to follow */
506  }else if (c_state == HEADER_SIZE) {
507  cmd = (uint8_t) (c & 0xFF);
508  //printf("cmd Value= %i\n",cmd );
509  checksum ^= (c & 0xFF);
511  }else if (c_state == HEADER_CMD && offset < dataSize) {
512  checksum ^= (c & 0xFF);
513  inputBuffer[offset++] = (uint8_t) (c & 0xFF);
514  if(cmd==108){
515  // Log.d("#########", "MSP_ATTITUDE: recived payload= "+inBuf[offset-1]);
516  }
517  }else if (c_state == HEADER_CMD && offset >= dataSize) {
518  /* compare calculated and transferred checksum */
519  if ((checksum & 0xFF) == (c & 0xFF)) {
520  if (err_rcvd) {
521  // Log.e("Multiwii protocol",
522  // "Copter did not understand request type " + c);
523  }else {
524  bufferIndex=0;
525  //printf("cmd Value= %i\n",cmd );
526  cout<<cmd;
527  }
528  }else
529  {
530 
531  }
532  c_state = IDLE;
533  }
534  // cout<<c_state;
535 }
536 
int offset
static const int HEADER_ERR
Definition: Protocol.h:55
uint8_t readSock(void *buf, int count)
uint8_t bufferIndex
Definition: Protocol.cpp:36
static const int HEADER_CMD
Definition: Protocol.h:55
int i
int checksumIndex
int8_t inputBuffer[1024]
Definition: Protocol.cpp:35
uint8_t command
int c_state
uint8_t checksum
uint8_t recbuf[1024]
int socketOpStarted
static const int HEADER_SIZE
Definition: Protocol.h:55
int dataSize
uint8_t readMulSock(void *buf, int count, int index)
uint8_t payload_size
bool err_rcvd
int indx
int writeMulSock(const void *buf, int count, int i)
static const int HEADER_ARROW
Definition: Protocol.h:55
int writeSock(const void *buf, int count)
void evaluateCommand(int command)
Definition: Protocol.cpp:84
void readMulFrame(int index)
socklen_t optlen
int optval
uint8_t c
static const int IDLE
Definition: Protocol.h:55
static const int HEADER_M
Definition: Protocol.h:55
bool connectMulSock(const std::string &ip, int index)
uint8_t cmd
Protocol pro
int socketSyckLock
static const int HEADER_START
Definition: Protocol.h:55
unsigned int len


edrone_client
Author(s): Simranjeet Singh
autogenerated on Sun Dec 1 2019 03:30:51