udev_control.cpp
Go to the documentation of this file.
1 // This file is part of the tcp/ip client library.
2 //
3 // Copyright (C) 2011 LAR - Laboratory for Automation and Robotics, ATLAS Project
4 // Department of Mechanical Engineering
5 // University of Aveiro
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2.1
10 // of the License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 // 02110-1301, USA.
21 
26 #include "udev_control.h"
27 
29 {
30  /* Create the udev object */
31  udev = udev_new();
32  if (!udev)
33  {
34  cout<<"Can't create udev!"<<endl;
35  return;
36  }
37 
38  id=id_;
39  fd=-1;
40 }
41 
43 {
44  udev_unref(udev);
45 }
46 
47 bool class_udev_control::RegistryAction(string action,void (*callback)(string action,string node,void*data),void*data)
48 {
49  actions[action]=callback;
50  user_data[action]=data;
51 
52  return true;
53 }
54 bool class_udev_control::AddProperty(string name,string value)
55 {
56  to_upper(name);
57  to_upper(value);
58 
59 // cout<<id<<", Added property: "<<name<<" value: "<<value<<endl;
60 
61  properties[name]=value;
62  return true;
63 }
64 
65 bool class_udev_control::AddSubsystem(string subsystem)
66 {
67 // cout<<id<<", Added subsytem: "<<subsystem<<endl;
68  sub_systems.push_back(subsystem);
69  return true;
70 }
71 
73 {
74  /* This section sets up a monitor which will report events when
75  devices attached to the system change. Events include "add",
76  "remove", "change", "online", and "offline".
77 
78  This section sets up and starts the monitoring. Events are
79  polled for (and delivered) later in the file.
80 
81  It is important that the monitor be set up before the call to
82  udev_enumerate_scan_devices() so that events (and devices) are
83  not missed. For example, if enumeration happened first, there
84  would be no event generated for a device which was attached after
85  enumeration but before monitoring began.
86 
87  Note that a filter is added so that we only get events for
88  "sub_systems" devices. */
89 
90  mon = udev_monitor_new_from_netlink(udev, "udev");
91 
92  for(uint i=0;i<sub_systems.size();i++)
93  udev_monitor_filter_add_match_subsystem_devtype(mon,sub_systems[i].c_str(),NULL);
94 
95  udev_monitor_enable_receiving(mon);
96  /* Get the file descriptor (fd) for the monitor.
97  This fd will get passed to select() */
98  fd = udev_monitor_get_fd(mon);
99  return true;
100 }
101 
102 string class_udev_control::GetProperty(struct udev_device *dev_,string name)
103 {
104  string value;
105  //error in the next line for gamepad on ubuntu 11.10
106 // cout << "GAMEPAD2" << endl;
107  value=udev_device_get_property_value(dev,name.c_str());
108 // cout << "GAMEPAD2.1" << endl;
109  return value;
110 }
111 
112 bool class_udev_control::FilterProperties(struct udev_device *dev_)
113 {
114  int num_properties_to_match=properties.size();
115  int num_properties_match=0;
116 
117 // cout<<"Num properties "<<num_properties_to_match<<endl;
118  struct udev_list_entry * sysattr_list;
119 
120  sysattr_list=udev_device_get_properties_list_entry(dev_);
121 
122  while(sysattr_list!=NULL)//get all parameters
123  {
124  string name=udev_list_entry_get_name(sysattr_list);
125  string value=udev_list_entry_get_value(sysattr_list);
126 
127  to_upper(name);
128  to_upper(value);
129 
130 // cout<<"Name "<<name<<" Value "<<value<<endl;
131 
132  properties_it=properties.find(name);
133  if(properties_it!=properties.end())//found
134  if(properties_it->second==value)
135  {
136 // cout<<"Matched "<<name<< " " <<value<<endl;
137  num_properties_match++;
138  }
139  sysattr_list=udev_list_entry_get_next(sysattr_list);
140  }
141 
142 // cout<<"Num matched "<<num_properties_match<<endl;
143 // if(num_properties_match==num_properties_to_match)
144 // {
145 // cout<<"Filtered sucessfully"<<endl;
146 // }
147 
148 
149  return num_properties_match==num_properties_to_match;
150 }
151 
153 {
154  /* Create a list of the devices in the 'sub_systems' subsystem. */
155  enumerate = udev_enumerate_new(udev);
156 
157  for(uint i=0;i<sub_systems.size();i++)
158  udev_enumerate_add_match_subsystem(enumerate,sub_systems[i].c_str());
159 
160  udev_enumerate_scan_devices(enumerate);
161  devices = udev_enumerate_get_list_entry(enumerate);
162 
163  /* For each item enumerated, print out its information.
164  udev_list_entry_foreach is a macro which expands to
165  a loop. The loop will be executed for each member in
166  devices, setting dev_list_entry to a list entry
167  which contains the device's path in /sys. */
168 
169  //The minor number is used to order the list of devices in tha case that there are more than one
170  string last_minor="0";
171  string minor;
172  udev_list_entry_foreach(dev_list_entry, devices)
173  {
174  const char *path;
175  string lpath;
176 
177  /* Get the filename of the /sys entry for the device
178  and create a udev_device object (dev) representing it */
179  path = udev_list_entry_get_name(dev_list_entry);
180  dev = udev_device_new_from_syspath(udev, path);
181 
182  if(FilterProperties(dev))
183  {
184 // cout << "GAMEPAD1" << endl;
185  //error in this line for gamepad
186  minor=GetProperty(dev,"MINOR");
187 // cout << "GAMEPAD1.1" << endl;
188  lpath=udev_device_get_devnode(dev);
189 
190  if(minor>last_minor)
191  device_list.push_back(lpath);
192  else
193  {
194  vector<string>::iterator it;
195  it=device_list.begin();
196  device_list.insert(it,lpath);
197  }
198 
199  cout<<"Added device to local list, ID: "<<id<<" Path: "<<lpath<<endl;
200 
201  last_minor=minor;
202  }
203 
204 
205 
206  udev_device_unref(dev);
207  }
208 
209  /* Free the enumerator object */
210  udev_enumerate_unref(enumerate);
211 
212  return true;
213 }
214 
215 
217 {
218  /* Begin polling for udev events. Events occur when devices
219  attached to the system are added, removed, or change state.
220  udev_monitor_receive_device() will return a device
221  object representing the device which changed and what type of
222  change occured.
223 
224  The select() system call is used to ensure that the call to
225  udev_monitor_receive_device() will not block.
226 
227  The monitor was set up earler in this file, and monitoring is
228  already underway.
229  */
230  /* Set up the call to select(). In this case, select() will
231  only operate on a single file descriptor, the one
232  associated with our udev_monitor. Note that the timeval
233  object is set to 0, which will cause select() to not
234  block. */
235  fd_set fds;
236  struct timeval tv;
237  int ret;
238 
239  FD_ZERO(&fds);
240  FD_SET(fd, &fds);
241  tv.tv_sec = 0;
242  tv.tv_usec = 0;
243 
244  if(fd<0)
245  {
246  cout<<"Monitoring was not configured, please run SetUpMonitoring() before calling Monitoring()"<<endl;
247  return false;
248  }
249 
250  ret = select(fd+1, &fds, NULL, NULL, &tv);
251 
252  /* Check if our file descriptor has received data. */
253  if (ret > 0 && FD_ISSET(fd, &fds))
254  {
255  /* Make the call to receive the device.
256  select() ensured that this will not block. */
257  dev = udev_monitor_receive_device(mon);
258  if (dev)
259  {
260  //dev is a udev_device
261 
262  if(FilterProperties(dev))//check if this is the correct device
263  {
264  actions_it=actions.find(udev_device_get_action(dev));
265  if(actions_it!=actions.end())
266  actions[udev_device_get_action(dev)](udev_device_get_action(dev),udev_device_get_devnode(dev),user_data[udev_device_get_action(dev)]);
267  }
268 
269  udev_device_unref(dev);
270  }
271  else
272  cout<<"No Device from receive_device(). An error occured."<<endl;
273  }
274 
275  return true;
276 }
struct udev_list_entry * devices
List entries.
Definition: udev_control.h:61
vector< string > device_list
List of all devices that pass the filter.
Definition: udev_control.h:122
struct udev * udev
Auxiliary variable.
Definition: udev_control.h:57
map< string, string > properties
Map of all properties added.
Definition: udev_control.h:71
bool AddProperty(string name, string value)
Add a property pair to the list of properties.
struct udev_monitor * mon
Udev monitor.
Definition: udev_control.h:65
map< string, void(*)(string, string, void *)>::iterator actions_it
Map iterator for the actions handler map.
Definition: udev_control.h:79
bool FilterProperties(struct udev_device *dev_)
Filter properties.
struct udev_list_entry * dev_list_entry
Definition: udev_control.h:61
string GetProperty(struct udev_device *dev_, string name)
Get device property.
map< string, void * > user_data
Map of pairs of actions strings and user data parameters.
Definition: udev_control.h:77
map< string, string >::iterator properties_it
Properties map iterator.
Definition: udev_control.h:73
bool RegistryAction(string action, void(*callback)(string action, string node, void *data), void *data)
Registry and action handler.
vector< string > sub_systems
Subsystem vector, these will be used to prefilter the devices.
Definition: udev_control.h:69
bool SetUpMonitoring()
Configure monitoring.
map< string, void(*)(string, string, void *)> actions
Map of pairs of actions strings and corresponding handler function.
Definition: udev_control.h:75
~class_udev_control()
Destructor.
bool AddSubsystem(string subsystem)
Add subsystem to the properties.
int fd
File descriptor used in the monitoring.
Definition: udev_control.h:67
bool Monitoring()
Monitor device.
Class that simplifies the implementation of the udev library.
struct udev_enumerate * enumerate
Enumerator auxiliary variable.
Definition: udev_control.h:59
bool EnumerateDevices()
Enumerate devices.
struct udev_device * dev
Device auxiliary variable.
Definition: udev_control.h:63
class_udev_control(string id_)
Constructor.


device_mapper
Author(s): Jorge Almeida
autogenerated on Mon Mar 2 2015 01:31:36