Main MRPT website > C++ reference for MRPT 1.5.9
CWirelessPower.cpp
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 
10 
11 
12 #include "hwdrivers-precomp.h" // Precompiled headers
13 
15 
16 using namespace mrpt::hwdrivers;
17 using namespace std;
18 
20 
22 {
23  m_sensorLabel = "WIRELESS_POWER";
24 }
25 
26 
27 #ifdef MRPT_OS_LINUX
28 #include <iostream>
29 #include <sstream>
30 #endif
31 
32 #ifdef MRPT_OS_WINDOWS
33  # if defined(__GNUC__)
34  // MinGW: Nothing to do here (yet)
35  # else
36 
37 #include <windows.h>
38 #include <wlanapi.h>
39 #include <objbase.h>
40 #include <wtypes.h>
41 #pragma comment(lib, "Wlanapi.lib")
42 
43  #endif
44 
45 #endif
46 
47 using namespace mrpt::utils;
48 
49 #ifdef MRPT_OS_WINDOWS
50  # if defined(__GNUC__)
51  // MinGW: Nothing to do here (yet)
52  # else
53 /*---------------------------------------------------------------
54  ConnectWlanServerW
55  Get a connection to the WLAN server
56  ---------------------------------------------------------------*/
57 
58  /** Gets a connection to the server
59  * \exception std::exception In case there is a failure (happens when WiFi is not started)
60  */
61 
62 void* ConnectWlanServerW()
63 {
64  DWORD dwMaxClient = 2;
65  DWORD dwCurVersion = 0;
66  DWORD dwResult = 0; // Result of the API call
67  HANDLE hClient;
68  // open connection to server
69  dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient);
70  if (dwResult != ERROR_SUCCESS) {
71  // if an error ocurred
72  std::stringstream excmsg;
73  excmsg << "WlanOpenHandle failed with error: " << dwResult << std::endl;
74 
75  // You can use FormatMessage here to find out why the function failed
76  THROW_EXCEPTION(excmsg.str());
77  }
78  return (void*)hClient;
79 }
80 
81 
82 /*---------------------------------------------------------------
83  ListInterfacesW
84  Gets a list of the interfaces (Windows)
85  ---------------------------------------------------------------*/
86 
87  /** Gets a list of the interfaces available in the system (in Windows format)
88  * \exception std::exception In case there is a failure
89  * \return std::vector returns handles to the available interfaces
90  */
91 
92 std::vector<PWLAN_INTERFACE_INFO> ListInterfacesW(HANDLE hClient)
93 {
94  // Get a list of the available interfaces
95 
96  std::vector<PWLAN_INTERFACE_INFO> outputVector; // start the output vector
97  PWLAN_INTERFACE_INFO_LIST pIfList = NULL; // list of WLAN interfaces
98  PWLAN_INTERFACE_INFO pIfInfo = NULL; // information element for one interface
99  DWORD dwResult = 0;
100 
101  int i;
102 
103 
104  // Call the interface enumeration function of the API
105  dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList);
106 
107  // check result
108  if (dwResult != ERROR_SUCCESS) {
109  // In case of error, raise an exception
110  std::stringstream excmsg;
111  excmsg << "WlanEnumInterfaces failed with error: " << dwResult << std::endl;
112 
113  THROW_EXCEPTION(excmsg.str());
114  // You can use FormatMessage here to find out why the function failed
115  } else {
116  // iterate throught interfaces to add them to the output vector
117  for (i = 0; i < (int) pIfList->dwNumberOfItems; i++) {
118 
119  pIfInfo = (WLAN_INTERFACE_INFO *) &pIfList->InterfaceInfo[i];
120  outputVector.push_back(pIfInfo);
121  }
122  }
123  return outputVector;
124 
125 }
126 
127 /*---------------------------------------------------------------
128  GUID2Str
129  Gets the GUID of a network based on its handler in Windows
130  ---------------------------------------------------------------*/
131  /** Transforms a GUID structure (in Windows format) to a string
132  * \exception std::exception In case there is a failure
133  * \return std::string returns a string containing the GUID
134  */
135 
136 std::string GUID2Str(const GUID &ifaceGuid)
137 {
138  // Variables
139  int iRet;
140  errno_t wctostr;
141  size_t sizeGUID;
142 
143  WCHAR GuidString[39] = {0};
144  char GuidChar[100];
145 
146 
147  std::string outputString;
148 
149  // Call the API function that gets the name of the GUID as a WCHAR[]
150  iRet = StringFromGUID2(ifaceGuid, (LPOLESTR) &GuidString, sizeof(GuidString)/sizeof(*GuidString));
151  // For c rather than C++ source code, the above line needs to be
152  // iRet = StringFromGUID2(&pIfInfo->InterfaceGuid, (LPOLESTR) &GuidString,
153  // sizeof(GuidString)/sizeof(*GuidString));
154 
155 
156  // translate from a WCHAR to string if no error happened
157  if (iRet == 0){
158  THROW_EXCEPTION("StringFromGUID2 failed\n");
159  } else {
160  wctostr = wcstombs_s(&sizeGUID, GuidChar, 100, GuidString, 100 );
161  if ( (wctostr == EINVAL) || (wctostr == ERANGE) ){
162  THROW_EXCEPTION("wcstombs_s failed\n");
163  } else {
164  outputString = std::string(GuidChar);
165  }
166  }
167 
168  return outputString;
169 }
170 
171 /*---------------------------------------------------------------
172  GetInterfaceW
173  Gets a handler for the interface (Windows)
174  ---------------------------------------------------------------*/
175 
176  /** Gets a handle to the interface that has been set by setNet() (in Windows format)
177  * \exception std::exception In case there is a failure
178  * \return PWLAN_INTERFACE_INFO returns a handle to the interface
179  */
180 
181 PWLAN_INTERFACE_INFO GetInterfaceW(std::string guid, HANDLE hClient)
182 {
183  // Get interface given the GUID as a string (by the guid property of the object)
184 
185 
186  std::vector<PWLAN_INTERFACE_INFO> ifaceList; // interface list
187  std::vector<PWLAN_INTERFACE_INFO>::iterator ifaceIter; // iterator
188  PWLAN_INTERFACE_INFO output = NULL; // interface info element
189 
190  // get a list of all the interfaces
191  ifaceList = ListInterfacesW(hClient);
192 
193  // search for the interface that has the given GUID
194  for(ifaceIter = ifaceList.begin(); ifaceIter != ifaceList.end(); ++ifaceIter){
195  if (GUID2Str((*ifaceIter)->InterfaceGuid) == guid){
196  output = *ifaceIter;
197  break;
198  }
199  }
200 
201  return output;
202 }
203 
204 
205 /*---------------------------------------------------------------
206  ListNetworksW
207  Gets a list of the networks available for the interface (in Windows)
208  ---------------------------------------------------------------*/
209 
210  /** Gets a list of the networks available for an interface (in Windows format)
211  * \exception std::exception In case there is a failure
212  * \return std::vector returns handles to the available networks of a given interface
213  * \param iface handle to the WiFi interface
214  */
215 std::vector<PWLAN_AVAILABLE_NETWORK> ListNetworksW(PWLAN_INTERFACE_INFO iface, HANDLE hClient)
216 {
217  // Start variables
218 
219  DWORD dwResult = 0;
220  PWLAN_AVAILABLE_NETWORK_LIST pBssList = NULL; // list of available networks
221  PWLAN_AVAILABLE_NETWORK pBssEntry = NULL; // information element for one interface
222 
223 
224  GUID ifaceGuid = iface->InterfaceGuid; // Get GUID of the interface
225 
226  std::vector<PWLAN_AVAILABLE_NETWORK> outputVector; // output vector
227 
228 // WCHAR GuidString[39] = {0};
229 
230  // Force a scan (to obtain new data)
231  WLAN_RAW_DATA IeData;
232  WlanScan((HANDLE)hClient, &ifaceGuid, NULL, &IeData, NULL);
233 
234  // Call the Windows API and get a list of the networks available through the interface
235  dwResult = WlanGetAvailableNetworkList((HANDLE)hClient, &ifaceGuid, 0, NULL, &pBssList);
236 
237  // Check the result of the call
238  if (dwResult != ERROR_SUCCESS) {
239  // In case an error ocurred
240  std::stringstream excmsg;
241  excmsg << "WlanGetAvailableNetworkList failed with error: " << dwResult << std::endl;
242  // THROW_EXCEPTION(excmsg.str());
243  } else {
244  // for each network, get its info and save it
245  for (unsigned int j = 0; j < pBssList->dwNumberOfItems; j++) {
246  pBssEntry = (WLAN_AVAILABLE_NETWORK *) & pBssList->Network[j]; // get entry for network
247  outputVector.push_back(pBssEntry); // save entry
248  }
249  }
250 
251  return outputVector;
252 }
253 
254 /*---------------------------------------------------------------
255  GetNetworkW
256  Gets a handler to a wireless network in Windows
257  ---------------------------------------------------------------*/
258 /** Gets a handle to the network that has been set by setNet() (in Windows format)
259  * \exception std::exception In case there is a failure
260  * \return PWLAN_AVAILABLE_NETWORK returns a handle to the network
261  */
262 PWLAN_AVAILABLE_NETWORK GetNetworkW(HANDLE hClient, const std::string &ssid, const std::string &guid)
263 {
264  // Variables
265  PWLAN_INTERFACE_INFO iface; // interface handler
266  PWLAN_AVAILABLE_NETWORK output; // output network handler
267 
268 
269  // Get a handler to the interface
270  iface = GetInterfaceW(guid, hClient);
271 
272  // Get the list of networks
273  std::vector<PWLAN_AVAILABLE_NETWORK> pBssList = ListNetworksW(iface,hClient);
274 
275 
276  // Iterate through the list and find the network that has the matching SSID
278  for(netIter = pBssList.begin(); netIter != pBssList.end() ; ++netIter){
279  if (std::string((char*)((*netIter)->dot11Ssid.ucSSID)) == ssid ){
280  output = *netIter;
281  break;
282  }
283  }
284 
285  return output;
286 }
287 
288  #endif
289 
290 #endif // end of Windows auxiliary functions definition
291 
292 
293 
294 /*---------------------------------------------------------------
295  ListInterfaces
296  Gets a list of the interfaces
297  ---------------------------------------------------------------*/
298 
299 std::vector<std::string> CWirelessPower::ListInterfaces()
300 {
301 
302  std::vector<std::string> output; // output vector of strings
303 
304 #ifdef MRPT_OS_LINUX
305  // in linux, the command line is used to get all the relevant information
306  FILE *cmdoutput; // file handler for the executed command line
307  char ifaceread[256],*netname; // strings used to read the output of the command line and get the name of each network
308 
309  // Run the command line: get the info frim /proc/net/wireless and cut out the names of the interfaces
310 
311  //commandl << "cat /proc/net/wireless|grep \"wlan\"|cut -d\" \" -f2|cut -d\":\" -f1";
312  cmdoutput = popen("cat /proc/net/wireless|grep \"wlan\"|cut -d\" \" -f2|cut -d\":\" -f1","r");
313  if (!fgets(ifaceread,3,cmdoutput)) // read output
314  THROW_EXCEPTION("Error reading /proc/net/wireless")
315 
316  // iterate thrugh list and get each interface as a string
317  netname = ::strtok(ifaceread,"\n");
318  while(netname){
319  output.push_back(std::string(netname));
320  netname = ::strtok(NULL,"\n");
321  }
322 #endif
323 
324 #ifdef MRPT_OS_WINDOWS
325  # if defined(__GNUC__)
326  THROW_EXCEPTION("Sorry, method not available for MinGW")
327  # else
328  // In windows, this function is a wrapper to ListInterfacesW
329 
330  std::vector<PWLAN_INTERFACE_INFO> ifaces; // vector containing the interface entries (Windows format)
331  std::vector<PWLAN_INTERFACE_INFO>::iterator ifacesIter; // iterator to run through the previous list
332 
333 
334  // get the list
335  ifaces = ListInterfacesW(hClient);
336 
337  // iterate thrugh list and get each GUID as a string
338  for (ifacesIter = ifaces.begin(); ifacesIter != ifaces.end() ; ++ifacesIter){
339  output.push_back(GUID2Str((*ifacesIter)->InterfaceGuid));
340  }
341  #endif
342 #endif
343 
344  return output;
345 }
346 
347 
348 /*---------------------------------------------------------------
349  ListNetworks
350  Gets a list of the networks available for the interface
351  ---------------------------------------------------------------*/
352 
353 std::vector<std::string> CWirelessPower::ListNetworks()
354 {
355 
356  std::vector<std::string> output; // output vector of strings
357 
358 #ifdef MRPT_OS_LINUX
359 
360  std::stringstream commandl; // command to be executed
361 
362  FILE *cmdoutput;
363  char listread[1024];
364  char *netname;
365 
366  // Run command: get a list of networks and cut out their names. Note: this must be done as a superuser, so the command is executed with sudo. Usually it should ask for the password only the first time.
367  // To avoid the inconvenience of having to write the password, it would be useful to configure sudo to allow the user to run this command. See "man sudoers"
368  commandl << "sudo iwlist " << "wlan0" << " scan|grep ESSID|cut -d\"\\\"\" -f2";
369  cmdoutput = popen(commandl.str().c_str(),"r");
370  if (!fgets(listread,3,cmdoutput))
371  THROW_EXCEPTION("Error reading response from iwlist")
372 
373  netname = ::strtok(listread,"\n");
374  while(netname){
375  output.push_back(std::string(netname));
376  netname = ::strtok(NULL,"\n");
377  }
378 
379 #endif
380 
381 #ifdef MRPT_OS_WINDOWS
382  # if defined(__GNUC__)
383  THROW_EXCEPTION("Sorry, method not available for MinGW")
384  # else
385 
386  PWLAN_INTERFACE_INFO iface; // Information element for an interface
387 
388 
389  iface = GetInterfaceW(guid,(HANDLE)hClient); // Get the interface handler
390 
391  // Get the list of networks
392  std::vector<PWLAN_AVAILABLE_NETWORK> pBssList = ListNetworksW(iface,(HANDLE)hClient);
393 
394  // Iterate through the list and save the names as strings
396  for(netIter = pBssList.begin(); netIter != pBssList.end() ; ++netIter){
397  output.push_back( std::string((char*)((*netIter)->dot11Ssid.ucSSID)));
398  }
399  #endif
400 
401 #endif
402 
403  return output;
404 
405 }
406 
407 
408 
409 /*---------------------------------------------------------------
410  GetPower
411  Gets the power of the network
412  ---------------------------------------------------------------*/
414 {
415 #ifdef MRPT_OS_LINUX
416  FILE *cmdoutput;
417  char *powerReadL;
418  std::stringstream commandl;
419  // Run command: get the power of the networks and additional info
420  commandl << "sudo iwlist " << "wlan0" << " scan";
421  cmdoutput = popen(commandl.str().c_str(),"r");
422 
423  std::vector<std::string> powerReadV;
424  size_t readBytes;
425 
426  powerReadL = (char *) malloc (256);
427  std::stringstream ssidLine;
428 
429  ssidLine << "ESSID:\"" << ssid << "\"";
430  if (getline(&powerReadL,&readBytes,cmdoutput)<0) THROW_EXCEPTION("Error reading response from iwlist")
431 
432  while(!strstr(powerReadL, ssidLine.str().c_str())){
433  powerReadV.push_back(std::string(powerReadL));
434  if (getline(&powerReadL,&readBytes,cmdoutput))
435  THROW_EXCEPTION("Error reading response from iwlist")
436  }
437 
438  std::vector<std::string>::iterator ssiter= powerReadV.end() - 2;
439 
440  char powerLine[256];
441 
442  // now we have a string per output line of iwlist. We must find the line containing the desired ESSID and read the power from two lines before
443 
444  strcpy(powerLine,(*ssiter).c_str());
445 
446  char level[10];
447  // meaning that the ESSID was found
448  // Example pf the value of poerLine: Quality=57/100 Signal level=57/100
449  char *fraction;
450 
451  ::strtok(powerLine,"=");
452  ::strtok(NULL,"=");
453  fraction = ::strtok(NULL,"=");
454  strcpy(level,::strtok(fraction,"/"));
455 
456  free(powerReadL);
457 
458  return atoi(level);
459 
460 #elif defined(MRPT_OS_WINDOWS)
461  # if defined(__GNUC__)
462  THROW_EXCEPTION("Sorry, method not available for MinGW")
463  # else
464  PWLAN_AVAILABLE_NETWORK wlan; // handler to the network
465 
466  // Get a handler to the network
467  wlan = GetNetworkW((HANDLE)hClient,ssid,guid);
468 
469  return wlan->wlanSignalQuality;
470  #endif
471 #else
472  THROW_EXCEPTION("Method not implemented for this platform/OS!");
473 #endif
474 
475 }
476 
477 
478 /*---------------------------------------------------------------
479  getObservation
480  Get the power of a given network as an observation
481  NOTE: Deprecated, use getObservations. Use this class as
482  GenericSensor. See the CGenericSensor documentation
483  ---------------------------------------------------------------*/
485 {
486  try{
487 
488  // outObservation.m_readings.clear();
489  outObservation.power = (float)GetPower();
490 
491  outObservation.timestamp = mrpt::system::getCurrentTime();
492 
493  outObservation.sensorLabel = m_sensorLabel;
494  // std::cout << "mrpt::hwdrivers::CWirelessPower::getObservation() " << "\n\tsensorLabel: " << outObservation.sensorLabel << "\n\ttimestamp: " << outObservation.timestamp << "\n\tpower: " << outObservation.power << std::endl;
495  return true;
496  }
497  catch(exception &e)
498  {
499  cerr << "[CWirelessPower::getObservation] Returning false due to exception: " << endl;
500  cerr << e.what() << endl;
501  return false;
502  }
503 }
504 
506 {
507  // Wrapper to getObservation
508  mrpt::obs::CObservationWirelessPowerPtr outObservation = mrpt::obs::CObservationWirelessPower::Create();
509  getObservation(*outObservation);
510 
511  appendObservation(mrpt::obs::CObservationWirelessPowerPtr(new mrpt::obs::CObservationWirelessPower(*outObservation)));
512 }
513 
514 
516  const mrpt::utils::CConfigFileBase &configSource,
517  const std::string &iniSection )
518 {
519  MRPT_START
520  pose_x = configSource.read_float(iniSection,"pose_x",0,true);
521  pose_y = configSource.read_float(iniSection,"pose_y",0,true);
522  pose_z = configSource.read_float(iniSection,"pose_z",0,true);
523  pose_roll = configSource.read_float(iniSection,"pose_roll",0,true);
524  pose_pitch = configSource.read_float(iniSection,"pose_pitch",0,true);
525  pose_yaw = configSource.read_float(iniSection,"pose_yaw",0,true);
526 
527  ssid = configSource.read_string(iniSection,"ssid","",true);
528  guid = configSource.read_string(iniSection,"guid","",true); // in the case of Linux, the "GUID" is the interface name (wlanX)
529 
530  #ifdef MRPT_OS_WINDOWS
531  # if defined(__GNUC__)
532  THROW_EXCEPTION("Sorry, method not available for MinGW")
533  # else
534  hClient = ConnectWlanServerW();
535  #endif
536  #endif
537 
538  MRPT_END
539 
540 }
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
Definition: zip.h:16
OBSERVATION_T::Ptr getObservation(mrpt::obs::CSensoryFramePtr &observations, mrpt::obs::CObservationPtr &observation, bool priority_to_sf=true)
Given an mrpt::obs::CSensoryFrame and a mrpt::obs::CObservation pointer if a OBSERVATION_T type obser...
Definition: obs_utils.h:32
float read_float(const std::string &section, const std::string &name, float defaultValue, bool failIfNotFound=false) const
void loadConfig_sensorSpecific(const mrpt::utils::CConfigFileBase &configSource, const std::string &section)
Loads specific configuration for the device from a given source of configuration parameters, for example, an ".ini" file, loading from the section "[iniSection]" (see utils::CConfigFileBase and derived classes)
mrpt::system::TTimeStamp BASE_IMPEXP getCurrentTime()
Returns the current (UTC) system time.
Definition: datetime.cpp:71
#define THROW_EXCEPTION(msg)
Scalar * iterator
Definition: eigen_plugins.h:23
Contains classes for various device interfaces.
std::string read_string(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
STL namespace.
static CObservationWirelessPowerPtr Create()
char BASE_IMPEXP * strcpy(char *dest, size_t destSize, const char *source) MRPT_NO_THROWS
An OS-independent version of strcpy.
Definition: os.cpp:296
This class allows loading and storing values and vectors of different types from a configuration text...
bool getObservation(mrpt::obs::CObservationWirelessPower &outObservation)
Gets the power of a given network as a timestamped observation NOTE: Deprecated, use getObservations ...
#define MRPT_END
This class implements a wireless power probe.
double power
The power or signal strength as sensed by the Wifi receiver (In percentage: [0-100]) ...
GLsizei const GLchar ** string
Definition: glext.h:3919
This represents a measurement of the wireless strength perceived by the robot.
#define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace)
This must be inserted in all CGenericSensor classes implementation files:
#define MRPT_START
std::string sensorLabel
An arbitrary label that can be used to identify the sensor.
mrpt::system::TTimeStamp timestamp
The associated UTC time-stamp. Where available, this should contain the accurate satellite-based time...
std::vector< std::string > ListNetworks()
Gets a list of the networks available for an interface.
std::vector< std::string > ListInterfaces()
Gets a list of the interfaces.
GLint level
Definition: glext.h:3545
int GetPower()
Gets the power of a given network.
char BASE_IMPEXP * strtok(char *str, const char *strDelimit, char **context) MRPT_NO_THROWS
An OS-independent method for tokenizing a string.
void doProcess()
This method will be invoked at a minimum rate of "process_rate" (Hz)



Page generated by Doxygen 1.8.14 for MRPT 1.5.9 Git: 690a4699f Wed Apr 15 19:29:53 2020 +0200 at miƩ abr 15 19:30:12 CEST 2020