TOBI SignalServer
0.1
|
00001 /* 00002 This file is part of the TOBI SignalServer. 00003 00004 Commercial Usage 00005 Licensees holding valid Graz University of Technology Commercial 00006 licenses may use this file in accordance with the Graz University 00007 of Technology Commercial License Agreement provided with the 00008 Software or, alternatively, in accordance with the terms contained in 00009 a written agreement between you and Graz University of Technology. 00010 00011 -------------------------------------------------- 00012 00013 GNU General Public License Usage 00014 Alternatively, this file may be used under the terms of the GNU 00015 General Public License version 3.0 as published by the Free Software 00016 Foundation and appearing in the file gpl.txt included in the 00017 packaging of this file. Please review the following information to 00018 ensure the GNU General Public License version 3.0 requirements will be 00019 met: http://www.gnu.org/copyleft/gpl.html. 00020 00021 In case of GNU General Public License Usage ,the TOBI SignalServer 00022 is distributed in the hope that it will be useful, 00023 but WITHOUT ANY WARRANTY; without even the implied warranty of 00024 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00025 GNU General Public License for more details. 00026 00027 You should have received a copy of the GNU General Public License 00028 along with the TOBI SignalServer. If not, see <http://www.gnu.org/licenses/>. 00029 00030 Copyright 2010 Graz University of Technology 00031 Contact: SignalServer@tobi-project.org 00032 */ 00033 00034 #include "hardware/mouse_win.h" 00035 #include "tia/constants.h" 00036 #include "boost/filesystem.hpp" 00037 00038 namespace tobiss 00039 { 00040 using std::string; 00041 00042 static const int LIBUSB_ERROR_PORT = -22; // by trial, no definitions where found in libusb-win32 00043 static const int LIBUSB_ERROR_TIMEOUT = -116; // by trial, no definitions where found in libusb-win32 00044 00045 const std::string Mouse::hw_dc_path_("devcon_path"); 00046 const std::string Mouse::hw_inf_file_path_("inf_file_path"); 00047 00048 const HWThreadBuilderTemplateRegistratorWithoutIOService<Mouse> Mouse::FACTORY_REGISTRATOR_ ("mouse"); 00049 00050 //----------------------------------------------------------------------------- 00051 00052 Mouse::Mouse(ticpp::Iterator<ticpp::Element> hw) 00053 : MouseBase(hw) 00054 { 00055 tia::Constants cst; 00056 ticpp::Iterator<ticpp::Element> ds(hw->FirstChildElement(hw_devset_, true)); 00057 00058 ticpp::Iterator<ticpp::Element> elem(ds->FirstChildElement(hw_dc_path_,true)); 00059 devcon_path_ = elem->GetText(true); 00060 size_t found = devcon_path_.find(" "); 00061 00062 if(found != string::npos) 00063 throw(std::runtime_error("MouseBase::Constructor -- Spaces in the devcon_path are forbidden!")); 00064 00065 if(!boost::filesystem::exists(devcon_path_.c_str())) 00066 throw(std::invalid_argument("Mouse::Constructor -- Devcon-path does not exist!")); 00067 00068 elem = ds->FirstChildElement(inf_file_path_,true); 00069 inf_file_path_ = elem->GetText(true); 00070 00071 if(!boost::filesystem::exists(inf_file_path_.c_str())) 00072 throw(std::invalid_argument("Mouse::Constructor -- Inf-file path does not exist!")); 00073 00074 string VID, PID; 00075 std::ostringstream v,p; 00076 v << std::setw(4) << std::setfill('0') << std::hex << vid_; 00077 p << std::setw(4) << std::setfill('0') << std::hex << pid_; 00078 VID = v.str(); 00079 PID = p.str(); 00080 hw_id_ = "\"USB\\VID_"+VID+"&PID_"+PID+"\""; 00081 00082 int ret = blockKernelDriver(); 00083 if(ret) 00084 throw(std::runtime_error("MouseBase::initMouse -- Mouse device could not be connected (check rights)!")); 00085 00086 setType("Mouse"); 00087 00088 } 00089 00090 //----------------------------------------------------------------------------- 00091 00092 Mouse::~Mouse() 00093 { 00094 running_ = false; 00095 async_acqu_thread_->join(); 00096 if(async_acqu_thread_) 00097 delete async_acqu_thread_; 00098 freeKernelDriver(); 00099 } 00100 00101 //----------------------------------------------------------------------------- 00102 00103 int Mouse::blockKernelDriver() 00104 { 00105 // create all parameter needed to open an extern tool (CreateProcess) 00106 STARTUPINFO siStartupInfo; 00107 PROCESS_INFORMATION piProcessInfo; 00108 memset(&siStartupInfo, 0, sizeof(siStartupInfo)); 00109 memset(&piProcessInfo, 0, sizeof(piProcessInfo)); 00110 siStartupInfo.cb = sizeof(siStartupInfo); 00111 00112 //disable the standard windows driver for the specific mouse device 00113 string command = "disable -r "+hw_id_; 00114 CreateProcess(const_cast<LPCSTR>(devcon_path_.c_str()), 00115 const_cast<LPSTR>(command.c_str()), 00116 0,0,FALSE,CREATE_NEW_CONSOLE,0,0,&siStartupInfo,&piProcessInfo); 00117 WaitForSingleObject(piProcessInfo.hProcess, 1000); 00118 00119 //load the new driver from the mouse.inf file 00120 00121 // const char *inf_file = "libusb/mouse.inf"; 00122 00123 int ret = usb_install_driver_np( inf_file_path_.c_str() ); 00124 if(ret<0) 00125 throw(std::runtime_error("Mouse::blockKernelDriver -- Could not install given .inf file!")); 00126 00127 // find the right usb-device and open it 00128 struct usb_bus *UsbBus = NULL; 00129 struct usb_device *UsbDevice = NULL; 00130 usb_find_busses(); 00131 usb_find_devices(); 00132 for (UsbBus = usb_get_busses(); UsbBus; UsbBus = UsbBus->next) { 00133 for (UsbDevice = UsbBus->devices; UsbDevice; UsbDevice = UsbDevice->next) { 00134 if (UsbDevice->descriptor.idVendor == vid_ && UsbDevice->descriptor.idProduct== pid_) { 00135 break; 00136 } 00137 } 00138 } 00139 if (!UsbDevice) 00140 return -1; 00141 dev_handle_ = usb_open(UsbDevice); 00142 if(!dev_handle_) 00143 return -11; 00144 00145 if (usb_set_configuration (dev_handle_, 1) < 0) { 00146 usb_close(dev_handle_); 00147 return -2; 00148 } 00149 00150 if (usb_claim_interface (dev_handle_, 0) < 0) { 00151 usb_close(dev_handle_); 00152 return -3; 00153 } 00154 00155 return 0; 00156 00157 } 00158 00159 //----------------------------------------------------------------------------- 00160 00161 int Mouse::freeKernelDriver() 00162 { 00163 // release the interface end close the usb-handle 00164 usb_release_interface(dev_handle_,0); 00165 usb_close(dev_handle_); 00166 00167 // create all parameter needed to open an extern tool (CreateProcess) 00168 STARTUPINFO siStartupInfo; 00169 PROCESS_INFORMATION piProcessInfo; 00170 memset(&siStartupInfo, 0, sizeof(siStartupInfo)); 00171 memset(&piProcessInfo, 0, sizeof(piProcessInfo)); 00172 siStartupInfo.cb = sizeof(siStartupInfo); 00173 00174 // remove the temporal driver from the mouse device 00175 string command = " remove -r "; 00176 command += hw_id_; 00177 CreateProcess(const_cast<LPCSTR>(devcon_path_.c_str()), 00178 const_cast<LPSTR>(command.c_str()), 00179 0,0,FALSE,CREATE_NEW_CONSOLE,0,0,&siStartupInfo,&piProcessInfo); 00180 WaitForSingleObject(piProcessInfo.hProcess, 1000); 00181 00182 // rescan for standard driver of the mouse device 00183 CreateProcess(const_cast<LPCSTR>(devcon_path_.c_str()), 00184 " rescan",0,0,FALSE,CREATE_NEW_CONSOLE,0,0,&siStartupInfo,&piProcessInfo); 00185 WaitForSingleObject(piProcessInfo.hProcess, 1000); 00186 00187 return 0; 00188 } 00189 00190 //----------------------------------------------------------------------------- 00191 00192 00193 void Mouse::acquireData() 00194 { 00195 while(running_) 00196 { 00197 bool unchanged = false; 00198 boost::unique_lock<boost::shared_mutex> lock(rw_); 00199 char async_data_[5]; 00200 int r = usb_interrupt_read(dev_handle_,usb_port_, async_data_, sizeof(async_data_), 10000); 00201 if(r == LIBUSB_ERROR_TIMEOUT){ 00202 //cout<<" Mouse: Timeout!"<<endl; 00203 unchanged = true; 00204 } 00205 else if(r == LIBUSB_ERROR_PORT){ 00206 lock.unlock(); 00207 throw(std::runtime_error("Mouse::acquireData -- Mouse device could not be read! Check usb-port!")); 00208 } 00209 else if(r<0){ 00210 lock.unlock(); 00211 throw(std::runtime_error("Mouse::acquireData -- Mouse device could not be read! Problem with libusb!")); 00212 } 00213 if(!unchanged){ 00214 async_data_buttons_ = static_cast<int>(static_cast<char>(async_data_[0])); 00215 async_data_x_ = static_cast<int>(static_cast<char>(async_data_[1])); 00216 async_data_y_ = static_cast<int>(static_cast<char>(async_data_[2])); 00217 } 00218 lock.unlock(); 00219 } 00220 } 00221 00222 //----------------------------------------------------------------------------- 00223 00224 00225 00226 } // Namespace tobiss 00227