socketComm.h
Go to the documentation of this file.
00001 /*****************************************************************************
00002  * @Brief     ROS-free and MavLink-free low-level socket communicator class
00003  * @Version   0.3.0
00004  * @Author    Chris Liu
00005  * @Created   2015/10/29
00006  * @Modified  2015/12/16
00007  *****************************************************************************/
00008 
00009 #ifndef _DJI2MAV_SOCKETCOMM_H_
00010 #define _DJI2MAV_SOCKETCOMM_H_
00011 
00012 
00013 #include <sys/socket.h>
00014 #include <sys/types.h>
00015 #include <netinet/in.h>
00016 #include <arpa/inet.h>
00017 #include <fcntl.h>
00018 #include <unistd.h>
00019 #include <time.h>
00020 #include <errno.h>
00021 
00022 #include "log.h"
00023 
00024 namespace dji2mav {
00025 
00026     class SocketComm {
00027         public:
00028             SocketComm() {
00029                 DJI2MAV_DEBUG("Construct SocketComm.");
00030                 m_sock = -1;
00031             }
00032 
00033 
00034             ~SocketComm() {
00035                 DJI2MAV_DEBUG("Going to destruct SocketComm...");
00036                 disconnect();
00037                 DJI2MAV_DEBUG("...finish destructing SocketComm.");
00038             }
00039 
00040 
00041             /* Set the Connection Configuration */
00042             void setConf(std::string gcsIP, uint16_t gcsPort, 
00043                     uint16_t locPort) {
00044 
00045                 DJI2MAV_DEBUG("Set SocketComm config IP: %s, destPort: %u, " 
00046                         "srcPort: %u", gcsIP.c_str(), gcsPort, locPort);
00047 
00048                 memset(&m_locAddr, 0, sizeof(m_locAddr));
00049                 m_locAddr.sin_family = AF_INET;
00050                 m_locAddr.sin_addr.s_addr = INADDR_ANY;
00051                 m_locAddr.sin_port = htons(locPort);
00052 
00053                 memset(&m_gcsAddr, 0, sizeof(m_gcsAddr));
00054                 m_gcsAddr.sin_family = AF_INET;
00055                 m_gcsAddr.sin_addr.s_addr = inet_addr(gcsIP.c_str());
00056                 m_gcsAddr.sin_port = htons(gcsPort);
00057 
00058             }
00059 
00060 
00061             /* Connect to the GCS */
00062             bool connect() {
00063 
00064                 DJI2MAV_INFO("Attempt to connect to %s:%u " 
00065                         "using local port %u...", 
00066                         inet_ntoa(m_gcsAddr.sin_addr), 
00067                         ntohs(m_gcsAddr.sin_port), 
00068                         ntohs(m_locAddr.sin_port) );
00069 
00070                 // Set socket properties. Using UDP
00071                 if((m_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
00072                     DJI2MAV_FATAL("...socket invalid!");
00073                     return false;
00074                 }
00075 
00076                 // Set the Communication Nonblocking
00077                 int flag = fcntl(m_sock, F_GETFL, 0);
00078                 if(fcntl(m_sock, F_SETFL, flag | O_NONBLOCK) < 0) {
00079                     DJI2MAV_FATAL("...set nonblocking socket fail!");
00080                     close(m_sock);
00081                     return false;
00082                 }
00083 
00084                 // Bind socket
00085                 if( -1 == bind(m_sock, (struct sockaddr *)&m_locAddr, 
00086                         sizeof(struct sockaddr_in)) ) {
00087                     DJI2MAV_FATAL("...bind socket fail!");
00088                     close(m_sock);
00089                     return false;
00090                 }
00091 
00092                 DJI2MAV_INFO("...connection succeed.");
00093                 m_timer = time(NULL);
00094                 return true;
00095 
00096             }
00097 
00098 
00099             /* Disconnect to the GCS */
00100             bool disconnect() {
00101 
00102                 DJI2MAV_DEBUG("Going to disconnect to %s:%u " 
00103                         "on local port %u...", 
00104                         inet_ntoa(m_gcsAddr.sin_addr), 
00105                         ntohs(m_gcsAddr.sin_port), 
00106                         ntohs(m_locAddr.sin_port) );
00107 
00108                 if(m_sock != -1) {
00109                     close(m_sock);
00110                     m_sock = -1;
00111                     DJI2MAV_DEBUG("...finish disconnecting.");
00112                     return true;
00113                 } else {
00114                     DJI2MAV_DEBUG("...no socke was binded.");
00115                     return false;
00116                 }
00117 
00118             }
00119 
00120 
00127             int send(uint8_t* sendBuf, uint16_t msglen) {
00128 
00129                 DJI2MAV_TRACE( "Send to %s:%u using port %u with %u bytes " 
00130                         "message.", inet_ntoa(m_gcsAddr.sin_addr), 
00131                         ntohs(m_gcsAddr.sin_port), ntohs(m_locAddr.sin_port), 
00132                         msglen );
00133 
00134                 // Using Nonblocking flag "MSG_DONTWAIT"
00135                 int ret = sendto( m_sock, sendBuf, msglen, MSG_DONTWAIT, 
00136                         (struct sockaddr *)&m_gcsAddr, 
00137                         sizeof(struct sockaddr_in) );
00138                 if(ret == -1)
00139                     DJI2MAV_ERROR("Fail to send message!");
00140                 else if(ret < msglen)
00141                     DJI2MAV_ERROR("Partial msg failed to send!");
00142 
00143                 return ret;
00144 
00145             }
00146 
00147 
00154             int recv(void* recvBuf, uint16_t maxBufLen) {
00155                 socklen_t l = sizeof(m_gcsAddr);
00156                 // Using Nonblocking flag "MSG_DONTWAIT"
00157                 int ret = recvfrom( m_sock, recvBuf, maxBufLen, MSG_DONTWAIT, 
00158                         (struct sockaddr *)&m_gcsAddr, &l );
00159                 if(ret == -1) {
00160                     if(errno != EAGAIN) {
00161                         DJI2MAV_ERROR("Fail to receive message!");
00162                         return -2;
00163                     }
00164                     if( m_timer + 10 < time(NULL) ) {
00165                         DJI2MAV_INFO("No datagram received in last 10 sec.");
00166                         m_timer = time(NULL);
00167                         return -1;
00168                     }
00169                 } else if(ret > 0) {
00170                     DJI2MAV_TRACE("Received %d bytes msg.", ret);
00171                     m_timer = time(NULL);
00172                     return ret;
00173                 } else if(0 == ret) {
00174                     DJI2MAV_ERROR( "The connection to %s:%u is closed!", 
00175                             inet_ntoa(m_gcsAddr.sin_addr), 
00176                             ntohs(m_gcsAddr.sin_port) );
00177                     return -2;
00178                 } else {
00179                     DJI2MAV_ERROR("Undefined return value %d while receiving " 
00180                             "datagram!", ret);
00181                     return -2;
00182                 }
00183             }
00184 
00185 
00186         private:
00187             struct sockaddr_in m_gcsAddr;
00188             struct sockaddr_in m_locAddr;
00189             int m_sock;
00190             long m_timer;
00191     };
00192 
00193 } //namespace dji2mav
00194 
00195 
00196 #endif


dji_sdk_dji2mav
Author(s):
autogenerated on Thu Jun 6 2019 17:55:35