TOBI SignalServer  0.1
/home/breidi/Dropbox/signalserver/src/hardware/mouse_win.cpp
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 
 All Data Structures Files Functions Variables