libcyberradio 22.01.24
ClientSocket.cpp
1/***************************************************************************
2 * \file ClientSocket.cpp
3 *
4 * \brief NDR651 client socket class.
5 *
6 * \author NH
7 * \copyright Copyright (c) 2015-2021 CyberRadio Solutions, Inc.
8 *
9 */
10
11#include "LibCyberRadio/Common/Pythonesque.h"
12#include "LibCyberRadio/NDR651/ClientSocket.h"
13
14
15namespace LibCyberRadio
16{
17 namespace NDR651
18 {
19 ClientSocket::ClientSocket(const std::string& hostname, unsigned int port,
20 bool debug) {
21 // TODO Auto-generated constructor stub
22 _serverHostname = hostname;
23 _serverPort = port;
24 _debug = debug;
25 }
26
28 // TODO Auto-generated destructor stub
29 disconnect();
30 }
31
33 struct sockaddr_in serv_addr;
34 struct hostent *server;
35 BasicStringList cmdVec, rspVec;
36 BasicStringList::iterator cmd, rsp;
37 bool cmdRspError = false;
38
39 //std::cout << "Client Connecting...";
40
41 server = gethostbyname(_serverHostname.c_str());
42 _sockfd = socket(AF_INET, SOCK_STREAM, 0);
43 bzero((char *) &serv_addr, sizeof(serv_addr));
44 serv_addr.sin_family = AF_INET;
45 bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
46 serv_addr.sin_port = htons(_serverPort);
47 if (connect(_sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) {
48 //std::cout << "ERROR?";
49 } else {
50 //std::cout << "success!";
51 _connected = true;
52 }
53 //std::cout << std::endl;
54
55 FD_ZERO(&set);
56 FD_SET(_sockfd, &set);
57
58 // Commenting this out because I make one TCP connection per command --JVM
59 //cmdVec.push_back(std::string("\n"));
60 //cmdVec.push_back(std::string("*IDN?\n"));
61 //cmdVec.push_back(std::string("VER?\n"));
62 //cmdVec.push_back(std::string("HREV?\n"));
63 // for (cmd=cmdVec.begin(); cmd<cmdVec.end(); cmd++) {
64 // rspVec.clear();
65 // cmdRspError |= sendCmdAndGetRsp(*cmd, rspVec, 2000, _debug);
66 // }
67
68 // Read radio connection greeting message (but do nothing)
69 struct timeval tout;
70 tout.tv_sec = 2;
71 tout.tv_usec = 0;
72 if (select(FD_SETSIZE, &set, NULL, NULL, &tout)>0)
73 {
74 _clearRxBuff();
75 _tcpRx();
76 }
77
78 return isConnected();
79 }
80
82 //std::cout << std::endl << "Client disconnecting...";
83 if (isConnected()) {
84 // shutdown(_sockfd,SHUT_WR);
85 // usleep(1000);
86 // shutdown(_sockfd,SHUT_RDWR);
87 // usleep(1000);
88 close(_sockfd);
89 _connected = false;
90 //std::cout << "success!";
91 } else {
92 //std::cout << "but we weren't connected?";
93 }
94 //std::cout << std::endl;
95
96 return !isConnected();
97 }
98
99 bool ClientSocket::sendCmd(const std::string& cmd) {
100 if (isConnected()) {
101 return write(_sockfd, cmd.c_str(), cmd.size())!=(int)cmd.size();
102 } else {
103 return true;
104 }
105 }
106
107 bool ClientSocket::getRsp(BasicStringList &rsp, float timeout) {
108 struct timeval tout;
109 tout.tv_sec = (long int) timeout/1000;
110 tout.tv_usec = (long int)(1000*timeout)%1000000;
111 _clearRxBuff();
112 FD_SET(_sockfd, &set);
113 if (select(FD_SETSIZE, &set, NULL, NULL, &tout)>0) {
114 _tcpRx();
115 rsp.push_back(std::string(_rxBuff));
116 return false;
117 } else {
118 return true;
119 }
120 }
121
122 bool ClientSocket::sendCmdAndGetRsp(const std::string& cmd, BasicStringList &rsp, float timeout) {
123 return sendCmdAndGetRsp(cmd, rsp, timeout, _debug);
124 }
125
126 bool ClientSocket::sendCmdAndGetRsp(const std::string& cmd, BasicStringList &rsp, float timeout, bool print) {
127 _trxMutex.lock();
128 unsigned int i;
129 std::string temp;
130 bool txError=false, rxError=false;
131 struct timeval tout;
132 tout.tv_sec = (long int) timeout/1000;
133 tout.tv_usec = (long int)(1000*timeout)%1000000;
134
135 txError = sendCmd(cmd);
136 FD_SET(_sockfd, &set);
137 while((!rxError)&&((rsp.size()==0)||((rsp.size()>0)&&(rsp.back().find("OK>")==std::string::npos)))) {
138 // txRxError = getRsp(rsp, timeout);
139 if (select(FD_SETSIZE, &set, NULL, NULL, &tout)>0) {
140 _clearRxBuff();
141 _tcpRx();
142 BasicStringList x = Pythonesque::Split(std::string(_rxBuff),"\n");
143 // std::cout << "\t** Separate strings in RSP = " << x.size() << std::endl;
144 for (i=0; i<x.size(); i++) {
145 temp = Pythonesque::Strip(x.at(i));
146 if (temp.size()>0) {
147 rsp.push_back(temp);
148 }
149 // std::cout << "\t** " << i << "(" << temp.size() << ") = '" << temp << "'" << std::endl;
150 }
151 // rsp.push_back(Pythonesque::Strip( std::string(_rxBuff) ));
152 } else {
153 rxError = true;
154 }
155 }
156 _trxMutex.unlock();
157 if (print) {
158 std::cerr << "CMD = '" << Pythonesque::Strip(cmd) << "' & RSP = '" << Pythonesque::Join(rsp, "; ") << "'" << std::endl;
159 for (BasicStringList::iterator it=rsp.begin(); it<rsp.end(); it++) {
160 std::cerr << "\tRSP = '" << *it << "'" << std::endl;
161 }
162 }
163 return txError||rxError;
164 }
165 }
166
167}
bool connectToServer(void)
Connects to the server.
bool isConnected(void)
Gets whether or not the socket is connected.
bool sendCmd(const std::string &cmd)
Sends a command to the server.
bool getRsp(BasicStringList &rsp, float timeout)
Gets a command response from the server.
virtual ~ClientSocket()
Destroys a ClientSocket object.
ClientSocket(const std::string &hostname, unsigned int port, bool debug=true)
Constructs a ClientSocket object.
bool disconnect(void)
Disconnects from the server.
bool sendCmdAndGetRsp(const std::string &cmd, BasicStringList &rsp, float timeout, bool print)
Sends a command to the server and gets the response.
static std::string Strip(const std::string &str, const std::string &chars=" \r\n\t\v\f")
Strips both leading and trailing whitespace from the given string.
static BasicStringList Split(const std::string &str, const std::string &sep, int maxsplit=INT_MAX)
Splits the given string into a list of string tokens.
static std::string Join(const BasicStringList &vec, const std::string &sep)
Joins a list of string tokens, concatenating them into a single string.
Provides programming elements for controlling the CyberRadio Solutions NDR651 radio.
Defines functionality for LibCyberRadio applications.
Definition App.h:24
BASIC_LIST_CONTAINER< std::string > BasicStringList
Type representing a list of strings.
Definition BasicList.h:25