00001
00002
00003
00004
00005
00006
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
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
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
00071 if((m_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
00072 DJI2MAV_FATAL("...socket invalid!");
00073 return false;
00074 }
00075
00076
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
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
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
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
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 }
00194
00195
00196 #endif