AudioManager  7.5.11
Native Application Runtime Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
CAmTelnetServer.cpp
Go to the documentation of this file.
1 
25 #include "CAmTelnetServer.h"
26 #include <cassert>
27 #include <sys/socket.h>
28 #include <arpa/inet.h>
29 #include <sys/ioctl.h>
30 #include <string.h>
31 #include <netdb.h>
32 #include <audiomanagerconfig.h>
33 #include <errno.h>
34 #include <sstream>
35 #include <istream>
36 #include <iostream>
37 #include <iterator>
38 #include <unistd.h>
39 #include <stdexcept>
40 #include <cstdlib>
41 #include "CAmRoutingSender.h"
42 #include "CAmTelnetMenuHelper.h"
43 #include "CAmDltWrapper.h"
44 
45 namespace am
46 {
47 
48 CAmTelnetServer* CAmTelnetServer::mpInstance = NULL;
49 
50 #define PRINT_BOOL(var) var ? output+="true\t\t" : output+="false\t\t";
51 
52 CAmTelnetServer::CAmTelnetServer(CAmSocketHandler *iSocketHandler, CAmCommandSender *iCommandSender, CAmCommandReceiver *iCommandReceiver, CAmRoutingSender *iRoutingSender, CAmRoutingReceiver *iRoutingReceiver, CAmControlSender *iControlSender, CAmControlReceiver *iControlReceiver, IAmDatabaseHandler *iDatabasehandler, CAmRouter *iRouter, unsigned int servPort, unsigned int maxConnections) :
53  telnetConnectFiredCB(this, &CAmTelnetServer::connectSocket), //
54  telnetReceiveFiredCB(this, &CAmTelnetServer::receiveData), //
55  telnetDispatchCB(this, &CAmTelnetServer::dispatchData), //
56  telnetCheckCB(this, &CAmTelnetServer::check), //
57  mpSocketHandler(iSocketHandler), //
58  mpCommandSender(iCommandSender), //
59  mpCommandReceiver(iCommandReceiver), //
60  mpRoutingSender(iRoutingSender), //
61  mpRoutingReceiver(iRoutingReceiver), //
62  mpControlSender(iControlSender), //
63  mpControlReceiver(iControlReceiver), //
64  mpDatabasehandler(iDatabasehandler), //
65  mpRouter(iRouter), //
66  mConnecthandle(), //
67  mListMessages(), //
68  mListConnections(), //
69  mConnectFD(0), //
70  mServerPort(servPort), //
71  mMaxConnections(maxConnections), //
72  mTelnetMenuHelper(iSocketHandler, iCommandSender, iCommandReceiver, iRoutingSender, iRoutingReceiver, iControlSender, iControlReceiver, iDatabasehandler, iRouter, this)
73 {
74  assert(mpSocketHandler!=NULL);
75  assert(mpCommandReceiver!=NULL);
76  assert(mpCommandSender!=NULL);
77  assert(mpControlSender!=NULL);
78  assert(mpControlReceiver!=NULL);
79  assert(mpRoutingSender!=NULL);
80  assert(mpRoutingReceiver!=NULL);
81  assert(mpDatabasehandler!=NULL);
82  assert(mpRouter!=NULL);
83  assert(servPort!=0);
84  assert(mMaxConnections!=0);
85 
86  mpInstance = this;
87  //mTelnetMenuHelper.setTelnetServer(this);
88 
89  int yes = 1;
90  struct sockaddr_in servAddr;
91 
92  //setup the port Listener
93  mConnectFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
94  assert (mConnectFD>0);
95  assert(setsockopt(mConnectFD, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int))==0);
96  memset(&servAddr, 0, sizeof(servAddr));
97  servAddr.sin_family = AF_INET;
98  servAddr.sin_addr.s_addr = INADDR_ANY;
99  servAddr.sin_port = htons(servPort);
100  if(bind(mConnectFD, (struct sockaddr *) &servAddr, sizeof(servAddr))!=0)
101  {
102  logError("CAmTelnetServer::CAmTelnetServer bind failed, error",errno);
103  throw std::runtime_error("CAmTelnetServer::CAmTelnetServer bind failed");
104  }
105 
106  if (listen(mConnectFD, mMaxConnections) < 0)
107  {
108  logError("TelnetServer::TelnetServerk cannot listen ", errno);
109  throw std::runtime_error("CAmTelnetServer::CAmTelnetServer bind failed");
110  }
111  else
112  logInfo("TelnetServer::TelnetServer started listening on port", mServerPort);
113 
114  int a = 1;
115  ioctl(mConnectFD, FIONBIO, (char *) &a);
116  setsockopt(mConnectFD, SOL_SOCKET, SO_KEEPALIVE, (char *) &a, sizeof(a));
117 
118  short events = 0;
119  events |= POLLIN;
120  mpSocketHandler->addFDPoll(mConnectFD, events, NULL, &telnetConnectFiredCB, NULL, NULL, NULL, mConnecthandle);
121 }
122 
124 {
125 }
126 
127 void CAmTelnetServer::connectSocket(const pollfd pfd, const sh_pollHandle_t handle, void *userData)
128 {
129  (void) handle;
130  (void) userData;
131  //first, accept the connection, create a new filedescriptor
132  struct sockaddr answer;
133  socklen_t len = sizeof(answer);
134  connection_s connection;
135  connection.handle = 0;
136  connection.filedescriptor = accept(pfd.fd, (struct sockaddr*) &answer, &len);
137 
138  assert(connection.filedescriptor>0);
139 
140  // Notiy menuhelper
141  mTelnetMenuHelper.newSocketConnection(connection.filedescriptor);
142 
143  //set the correct event:
144  short event = 0;
145  event |= POLLIN;
146 
147  //add the filedescriptor to the sockethandler and register the callbacks for receiving the data
148  mpSocketHandler->addFDPoll(connection.filedescriptor, event, NULL, &telnetReceiveFiredCB, &telnetCheckCB, &telnetDispatchCB, NULL, connection.handle);
149  mListConnections.push_back(connection);
150 }
151 
152 void CAmTelnetServer::disconnectClient(int filedescriptor)
153 {
154  std::vector<connection_s>::iterator iter = mListConnections.begin();
155  while (iter != mListConnections.end())
156  {
157  if (filedescriptor == iter->filedescriptor)
158  {
159  if (E_OK == mpSocketHandler->removeFDPoll(iter->handle))
160  {
161  mListConnections.erase(iter);
162  close(filedescriptor);
163  }
164  else
165  {
166  // TODO: Handle error
167  }
168 
169  break;
170  }
171  iter++;
172  }
173 }
174 
175 void CAmTelnetServer::receiveData(const pollfd pollfd, const sh_pollHandle_t handle, void *userData)
176 {
177  (void) handle;
178  (void) userData;
179  //initialize buffer
180  char buffer[100];
181  //read until buffer is full or no more data is there
182  int read = recv(pollfd.fd, buffer, 100, 0);
183  if (read > 1)
184  {
185  //read the message and store it in a queue - its a telnet connection so data will be sent on enter !
186  std::string msg = std::string(buffer, read);
187  mListMessages.push(msg);
188  }
189 }
190 
191 bool CAmTelnetServer::dispatchData(const sh_pollHandle_t handle, void *userData)
192 {
193  (void) userData;
194  std::vector<connection_s>::iterator iterator = mListConnections.begin();
195  for (; iterator != mListConnections.end(); ++iterator)
196  {
197  if (iterator->handle == handle)
198  break;
199  }
200  if (iterator==mListConnections.end())
201  {
202  logError("CAmTelnetServer::dispatchData could not find handle !");
203  return (false);
204  }
205 
206  std::string command;
207  std::queue<std::string> MsgQueue;
208  if (!mListMessages.empty())
209  {
210  sliceCommand(mListMessages.front(), command, MsgQueue);
211  mListMessages.pop();
212  mTelnetMenuHelper.enterCmdQueue(MsgQueue, iterator->filedescriptor);
213  }
214  else
215  {
216  logError("CAmTelnetServer::dispatchData Message queue was empty!");
217  }
218 
219  // must return false to stop endless polling
220  return (false);
221 }
222 
223 bool CAmTelnetServer::check(const sh_pollHandle_t handle, void *userData)
224 {
225  (void) handle;
226  (void) userData;
227  if (mListMessages.size() != 0)
228  return (true);
229  return (false);
230 }
231 
232 void am::CAmTelnetServer::sliceCommand(const std::string & string, std::string & command, std::queue<std::string> & MsgQueue)
233 {
234  (void) command;
235  std::stringstream stream(string);
236  std::istream_iterator<std::string> begin(stream);
237  std::istream_iterator<std::string> end;
238  std::string cmd;
239  bool endOfStream = false;
240 
241  int c = 0;
242 
243  while (!endOfStream)
244  {
245  cmd = *begin;
246  MsgQueue.push(cmd);
247  begin++;
248 
249  if (begin == end)
250  {
251  endOfStream = true;
252  }
253  c++;
254  }
255 }
256 }
257 
Implements the RoutingSendInterface.
This class realizes the command Interface.
SPDX license identifier: MPL-2.0.
void logInfo(T value, TArgs...args)
logs given values with infolevel with the default context
bool check(const sh_pollHandle_t handle, void *userData)
Implements an autorouting algorithm for connecting sinks and sources via different audio domains...
Definition: CAmRouter.h:152
This class is used to receive all commands from the control interface.
The am::CAmSocketHandler implements a mainloop for the AudioManager.
void connectSocket(const pollfd pfd, const sh_pollHandle_t handle, void *userData)
uint16_t sh_pollHandle_t
this is a handle for a filedescriptor to be used with the SocketHandler
SPDX license identifier: MPL-2.0.
am_Error_e removeFDPoll(const sh_pollHandle_t handle)
removes a filedescriptor from the poll loop
Implements the Receiving side of the RoutingPlugins.
SPDX license identifier: MPL-2.0.
am_Error_e addFDPoll(const int fd, const short event, IAmShPollPrepare *prepare, IAmShPollFired *fired, IAmShPollCheck *check, IAmShPollDispatch *dispatch, void *userData, sh_pollHandle_t &handle)
Adds a filedescriptor to the polling loop.
void disconnectClient(int filedescriptor)
void newSocketConnection(int filedescriptor)
sends data to the commandInterface, takes the file of the library that needs to be loaded ...
This class handles and abstracts the database.
SPDX license identifier: MPL-2.0.
Implements a telnetserver that can be used to connect to the audiomanager, retrieve some information ...
CAmTelnetServer(CAmSocketHandler *iSocketHandler, CAmCommandSender *iCommandSender, CAmCommandReceiver *iCommandReceiver, CAmRoutingSender *iRoutingSender, CAmRoutingReceiver *iRoutingReceiver, CAmControlSender *iControlSender, CAmControlReceiver *iControlReceiver, IAmDatabaseHandler *iDatabasehandler, CAmRouter *iRouter, unsigned int servPort, unsigned int maxConnections)
void enterCmdQueue(std::queue< std::string > &CmdQueue, int &filedescriptor)
TAmShPollCheck< CAmTelnetServer > telnetCheckCB
bool dispatchData(const sh_pollHandle_t handle, void *userData)
TAmShPollDispatch< CAmTelnetServer > telnetDispatchCB
void logError(T value, TArgs...args)
logs given values with errorlevel with the default context
no error - positive reply
TAmShPollFired< CAmTelnetServer > telnetReceiveFiredCB
This class is used to send data to the CommandInterface.
void receiveData(const pollfd pfd, const sh_pollHandle_t handle, void *userData)
TCLAP::ValueArg< unsigned int > maxConnections("m","maxConnections","Maximal number of connections for telnet", false, MAX_TELNETCONNECTIONS,"int")
TAmShPollFired< CAmTelnetServer > telnetConnectFiredCB