TUsb Respiration Belt plugin 1.0

lib/LSerie.cpp

00001 #include <windows.h>
00002 #include <stdio.h>
00003 #include "winuser.h"
00004 #include "LSerie.h"
00005 //#include "plugin.h"
00006 #include <setupapi.h>
00007 
00009 // Construction/Destruction
00011 
00014 LSerie::LSerie()
00015 {
00016         hcom = 0;       //Fichier de sortie sur le port COM             | The file stream use for acces to the serial port.
00017         bufferSize = 8192;      // Buffer d'entrée sortie.
00018   currentPort = -1;
00019 }
00020 
00021 LSerie::~LSerie()
00022 {
00023   closeCom();
00024 }
00025 
00026 bool LSerie::CheckPort(unsigned int num)
00027 { 
00028   // Create a device information set that will be the container for 
00029   // the device interfaces.
00030   GUID *guidDev = (GUID*) &GUID_CLASS_COMPORT;
00031   HDEVINFO hDevInfo = INVALID_HANDLE_VALUE;
00032   SP_DEVICE_INTERFACE_DETAIL_DATA *pDetData = NULL;
00033   SP_DEVICE_INTERFACE_DATA ifcData;
00034   BOOL bOk = true;
00035 
00036   hDevInfo = SetupDiGetClassDevs( guidDev,NULL,NULL,DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
00037 
00038   if(hDevInfo == INVALID_HANDLE_VALUE) 
00039   {
00040     return false;
00041   }
00042 
00043   DWORD dwDetDataSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + 256;
00044   pDetData = (SP_DEVICE_INTERFACE_DETAIL_DATA*) new char[dwDetDataSize];
00045   ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
00046   pDetData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
00047 
00048   bOk = SetupDiEnumDeviceInterfaces(hDevInfo,NULL, guidDev, num, &ifcData);
00049   if (!bOk) 
00050   {
00051     return false;
00052   }
00053 
00054   // Got a device. Get the details.
00055   SP_DEVINFO_DATA devdata = {sizeof(SP_DEVINFO_DATA)};
00056   bOk = SetupDiGetDeviceInterfaceDetail(hDevInfo,&ifcData, pDetData, dwDetDataSize, NULL, &devdata);
00057   if (!bOk) 
00058   {
00059     return false;
00060   }
00061 
00062   std::string strDevPath(pDetData->DevicePath);
00063   // Got a path to the device. Try to get some more info.
00064   TCHAR fname[256];
00065   TCHAR desc[256];
00066   TCHAR szPortName[MAX_PATH];
00067   bool bUsbDevice = FALSE;
00068   TCHAR locinfo[256];
00069 
00070   bOk = SetupDiGetDeviceRegistryProperty(hDevInfo, &devdata, SPDRP_FRIENDLYNAME, NULL,(PBYTE)fname, sizeof(fname), NULL);
00071 
00072   bOk = bOk && SetupDiGetDeviceRegistryProperty(hDevInfo, &devdata, SPDRP_DEVICEDESC, NULL,(PBYTE)desc, sizeof(desc), NULL);
00073 
00074   SetupDiGetDeviceRegistryProperty(hDevInfo, &devdata, SPDRP_LOCATION_INFORMATION, NULL,(PBYTE)locinfo, sizeof(locinfo), NULL);
00075 
00076   HKEY hKey = SetupDiOpenDevRegKey(hDevInfo, &devdata, DICS_FLAG_GLOBAL,0,DIREG_DEV,KEY_READ);
00077 
00078   DWORD dwType = REG_SZ;
00079   DWORD dwReqSize = sizeof(szPortName);
00080   long lRet = RegQueryValueEx(hKey,"PortName", 0, &dwType, (LPBYTE)&szPortName, &dwReqSize);
00081     
00082   if (pDetData != NULL)
00083   {
00084     delete [] (char*)pDetData;
00085   }
00086   if (hDevInfo != INVALID_HANDLE_VALUE)
00087   {
00088     SetupDiDestroyDeviceInfoList(hDevInfo);
00089   }
00090 
00091   if(hKey && bOk)
00092   {
00093     return true;
00094   }
00095   return false;
00096 }
00097 
00098 bool LSerie::open(int numPort, long speedInBaud)
00099 {
00100         return open(numPort, speedInBaud, 8, 0, 1);
00101 }
00102 
00103 
00104 /************************************************************************************
00105 **** Fonction: Open
00106 **** Derniére modif: 21/05/2005
00107 **** Développeur: Alexandre Fonton
00108 **** Rôle: Ouvre le port RS232 choisi. 
00109 **** Recoit: 
00110 **** Renvoie: Faux si l'ouverture du port a échoué, sinon Vrai.
00111 *************************************************************************************/
00112 
00113 bool LSerie::open(int numPort, long speedInBaud, int nbBit, int parity, float nbStopBit)
00114 {       
00115   char buf[13];
00116   buf[0]=0;
00117 
00118         //--- Vérification des paramétres passés à la fonction:
00119         if(numPort<1 || numPort>256)            // Vérification que le numéro de port est compri entre 1 et 9.
00120                 return false;
00121 
00122         if(speedInBaud<1)               // Vérification de la vitesse de communication
00123                 return false;
00124 
00125         if(nbBit<5 || nbBit > 9)
00126                 return false;
00127 
00128         if(parity<0 || parity > 2)
00129                 return false;
00130 
00131         if(nbStopBit<1 || nbStopBit > 2)
00132                 return false;
00133 
00134         //--- Création d'une chaine de caractère contenant le nom du port série, ex : COM1.
00135 
00136   sprintf(buf, "\\\\.\\COM%i", numPort);
00137 
00138         //--- Ouverture du port série en lecture / écriture.v
00139 
00140   hcom=CreateFile(buf, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING , FILE_FLAG_WRITE_THROUGH, 0);
00141         if (hcom==0 || hcom==INVALID_HANDLE_VALUE)
00142   {
00143     //std::string err = getErrorMsg();
00144                 return false;
00145   }
00146 
00147   //--- Définit la durée du TimeOut pour la reception.
00148   setTimeOut(DISCONNECTION_WIN_TIME);
00149 
00150         //--- Dimensionne les buffers d'entrée et sortie.
00151         if ( !SetupComm(hcom, bufferSize, bufferSize) )     
00152             return false;
00153 
00154         //--- Récupére l'objet de configuration du format des bytes.
00155     if ( !GetCommState(hcom, &dcb))
00156                 return false;
00157 
00158         //Vitesse de communication
00159         dcb.BaudRate = speedInBaud;
00160 
00161         //Nombre de bit par byte:
00162         dcb.ByteSize = nbBit;
00163         
00164         //Nombre de bit de stop: 1, 1.5 ou 2
00165         if(nbStopBit == 1)
00166                 dcb.StopBits = ONESTOPBIT;
00167         if(nbStopBit == 1.5)
00168                 dcb.StopBits = ONE5STOPBITS;
00169         if(nbStopBit == 2)
00170                 dcb.StopBits = TWOSTOPBITS;
00171         
00172         //Vérification de la parité: 0 pas de vérif, 1 pair, 2 impaire.
00173         if(parity == 0)
00174                 dcb.Parity = NOPARITY;
00175         if(parity == 1)
00176                 dcb.Parity = ODDPARITY;
00177         if(parity == 2)
00178                 dcb.Parity = EVENPARITY;
00179         
00180         // ajoute le handle pour scol
00181         comport = hcom;
00182 
00183   currentPort = numPort;
00184 
00185         //--- Stocke l'objet de configuration du format des bytes.
00186           if (!SetCommState(hcom, &dcb))
00187                 return false;
00188           else
00189                 return true;
00190 }
00191 
00192 
00193 /************************************************************************************
00194 **** Fonction: CloseCom
00195 **** Derniére mofif: 01/07/2004
00196 **** Développeur: Alexandre Fonton
00197 **** Rôle: Ferme le port RS232 actuellement ouvert.
00198 **** Recoit: Rien
00199 **** Renvoie: Rien
00200 *************************************************************************************/
00201 
00202 void LSerie::closeCom()
00203 {
00204   if(hcom)
00205   {
00206           CloseHandle(hcom);
00207           hcom = 0;
00208   }
00209 }
00210 
00211 /************************************************************************************
00212 **** Fonction: SetTimeout
00213 **** Derniére mofif: 01/07/2004
00214 **** Développeur: Alexandre Fonton
00215 **** Rôle: Définit la durée maximum d'attente d'une information (TimeOut).
00216 **** Recoit: Temps d'attente en ms.
00217 **** Renvoie: Faux si l'opération a échoué, sinon Vrai.
00218 *************************************************************************************/
00219 
00220 bool LSerie::setTimeOut(DWORD ms)
00221 {
00222         //--- Vérification des paramétres passés à la fonction:
00223         if( ms<0)
00224                 return false;
00225 
00226         ct.ReadIntervalTimeout = 0;
00227         ct.ReadTotalTimeoutMultiplier = 0;      // pas de multipicateur de timeout en fonction du nombre de caractères demandés.
00228         ct.ReadTotalTimeoutConstant = ms;
00229         ct.WriteTotalTimeoutMultiplier = 0;
00230         ct.WriteTotalTimeoutConstant = ms;
00231         if ( !SetCommTimeouts(hcom, &ct) )      //Configuration du Time Out
00232                 return false;
00233         return false;
00234         //MSDN: The SetCommTimeouts function sets the time-out parameters for all read and write operations on a specified communications device.
00235 }
00236 
00237 /**********************************************************************
00238 **** Fonction: SetBaud
00239 **** Derniére mofif: 01/07/2004
00240 **** Développeur: Alexandre Fonton
00241 **** Rôle: Définit la vitesse de communication (ex:9600 baud).
00242 **** Recoit: Vitesse de communication en baud.
00243 **** Renvoie: Faux si l'opération a échoué, sinon Vrai.
00244 ***********************************************************************/
00245 
00246 bool LSerie::setSpeed(DWORD baudrate)
00247 {
00248         //--- Vérification des paramétres passés à la fonction:
00249         if( baudrate<1)
00250                 return false;
00251 
00252 
00253         if (!GetCommState(hcom, &dcb))
00254                 return FALSE;
00255 
00256         dcb.BaudRate = baudrate;
00257 
00258         if (!SetCommState(hcom, &dcb))
00259                 return FALSE;
00260         else 
00261                 return TRUE;
00262 
00263 
00264         
00265 
00266         //MSDN: The SetCommState function configures a communications device according to the specifications in a device-control block (a DCB structure). The function reinitializes all hardware and control settings, but it does not empty output or input queues.
00267 }
00268 
00269 
00270 
00271 /**********************************************************************
00272 **** Fonction: SendData(string)
00273 **** Derniére mofif: 22/05/2005
00274 **** Développeur: Alexandre Fonton
00275 **** Rôle: Envoie une chaine de caractères contenu dans un type "string" sur le port RS232 actuellement ouvert.
00276 **** Recoit: Un pointeur sur une chaine de caractéres.
00277 **** Renvoie: -1 si l'opération a échoué, sinon le nombre de caractères envoyés.
00278 ***********************************************************************/
00279 
00280 int  LSerie::sendData(string* data)
00281 {
00282         //--- Vérification des paramétres passés à la fonction:
00283         if( data == NULL )
00284                 return false;
00285 
00286         return sendData((DWORD)data->size(), (LPBYTE)data->data());
00287 }
00288 
00289 
00290 
00291 /**********************************************************************
00292 **** Fonction: SendData(DWORD lg, LPBYTE data)
00293 **** Derniére mofif: 01/07/2004
00294 **** Développeur: Alexandre Fonton
00295 **** Rôle: Envoie une série d'octets sur le port RS232 actuellement ouvert.
00296 **** Recoit: Un pointeur sur une chaine de caractéres (data) et sa taille (lg).
00297 **** Renvoie: -1 si l'opération a échoué, sinon le nombre de caractères envoyés.
00298 ***********************************************************************/
00299 int LSerie::sendData(DWORD lg, LPBYTE data)
00300 {
00301         DWORD result=0;
00302 
00303         //--- Vérification des paramétres passés à la fonction:
00304         if( lg<0 || data==NULL)
00305                 return false;
00306 
00307 
00308         if ( !WriteFile(hcom, data, lg, &result, 0) )
00309                 return -1;
00310         else
00311                 return (int)result;
00312 
00313         //MSDN:  The WriteFile function writes data to a file and is designed for both synchronous
00314         //              and asynchronous operation. The function starts writing data to the file at the 
00315         //              position indicated by the file pointer. After the write operation has been completed
00316         //              , the file pointer is adjusted by the number of bytes actually written, except when
00317         //              the file is opened with FILE_FLAG_OVERLAPPED. If the file handle was created for 
00318         //              overlapped input and output (I/O), the application must adjust the position of the
00319         //              file pointer after the write operation is finished.
00320     //       This function is designed for both synchronous and asynchronous operation. 
00321         //              The WriteFileEx function is designed solely for asynchronous operation. 
00322         //              It lets an application perform other processing during a file write operation.
00323 
00324 }
00325 
00326 
00327 
00328 
00329 
00330 
00331 
00332 /**********************************************************************
00333 **** Fonction: ReceiveData(string* data)
00334 **** Derniére mofif: 22/05/2005
00335 **** Développeur: Alexandre Fonton
00336 **** Rôle: Lecture du buffer de reception du port RS232 actuellement ouvert.
00337 **** Recoit: Un pointeur sur une string.
00338 **** Renvoie: -1 si l'opération a échoué, sinon le nombre de caractères recu.
00339 ***********************************************************************/
00340 int LSerie::receiveData(string* data)
00341 {       char buffer[1025];
00342         int nbChar=0;
00343 
00344         //--- Vérification des paramétres passés à la fonction:
00345         if( data==NULL)
00346                 return false;
00347 
00348         nbChar = receiveData(1024, (LPBYTE)buffer);
00349         buffer[nbChar] = 0; // caractère de fin de chaine.
00350         data->assign(buffer);
00351         return nbChar;
00352 }
00353 
00354 
00355 /**********************************************************************
00356 **** Fonction: ReceiveData
00357 **** Derniére mofif: 01/07/2004
00358 **** Développeur: Alexandre Fonton
00359 **** Rôle: Lecture du buffer de reception du port RS232 actuellement ouvert.
00360 **** Recoit: Un pointeur sur une chaine de caractéres (data) et sa taille maximale possible (lg).
00361 **** Renvoie: -1 si l'opération a échoué, sinon le nombre de caractères recu.
00362 ***********************************************************************/
00363 int LSerie::receiveData(DWORD lg, LPBYTE data)
00364 {
00365         DWORD result=0;
00366 
00367         //--- Vérification des paramétres passés à la fonction:
00368         if( lg<0 || data==NULL)
00369                 return false;
00370 
00371   if (ReadFile(hcom, data, lg, &result, 0))
00372   {
00373     return (int)result;
00374   }
00375   else
00376   {
00377     return -1;
00378   }
00379 
00380         //MSDN:   The ReadFile function reads data from a file, starting at the position indicated 
00381         //               by the file pointer. After the read operation has been completed, the file pointer
00382         //               is adjusted by the number of bytes actually read, unless the file handle is 
00383         //               created with the overlapped attribute. If the file handle is created for 
00384         //               overlapped input and output (I/O), the application must adjust the position of 
00385         //               the file pointer after the read operation.
00386         //        This function is designed for both synchronous and asynchronous operation. 
00387         //               The ReadFileEx function is designed solely for asynchronous operation. It lets 
00388         //               an application perform other processing during a file read operation.
00389 
00390 }
00391 
00392 
00393 /**************************** SetRts(val) **************************************************
00394 **** Positionne RTS au niveau val (0 ou 1)   */
00395 bool LSerie::setRts(bool val)                           
00396 { 
00397         if(val)
00398           { 
00399                   if(EscapeCommFunction(hcom, SETRTS) == TRUE )
00400                           return true;
00401           }
00402         else
00403           { 
00404                   if(EscapeCommFunction(hcom, CLRRTS) == TRUE )
00405                           return true;
00406           }
00407 
00408    return false;
00409 }
00410 
00411 
00412 /**************************** SetTxd(val) **************************************************
00413 **** Positionne Txd au niveau val (0 ou 1)   */
00414 bool LSerie::setTxd(bool val)                           
00415 { 
00416         if(val)
00417           { 
00418                   if( EscapeCommFunction(hcom, SETBREAK) == TRUE )
00419                           return true;
00420           }
00421         else
00422           { 
00423                   if( EscapeCommFunction(hcom, CLRBREAK) == TRUE )
00424                           return true;
00425           }
00426    return false;
00427 }
00428 
00429 
00430         
00431 /**************************** SetDtr(val) **************************************************
00432 **** Positionne DTR au niveau val (0 ou 1)   */
00433 bool LSerie::setDtr(bool val)                                           
00434 { 
00435         if(val)
00436           {
00437                   if( EscapeCommFunction(hcom, SETDTR) == TRUE )
00438                           return true;
00439           }
00440         else
00441           { 
00442                   if( EscapeCommFunction(hcom, CLRDTR) == TRUE )
00443                           return false;
00444           }
00445     return false;
00446 }
00447 
00448 
00449 
00450 /********************** GetCts() ***********************/
00451 bool LSerie::getCts()                                           
00452 { 
00453         DWORD result;
00454                 GetCommModemStatus(hcom, &result);
00455                 if(result & MS_CTS_ON)
00456                         return true;
00457                 else
00458                         return false;
00459 }
00460 
00461 /********************** GetDtr() ***********************/
00462 bool LSerie::getDtr()                                           
00463 { 
00464   DWORD result;
00465                 GetCommModemStatus(hcom, &result);
00466                 if(result & MS_DSR_ON)
00467                         return true;
00468                 else
00469                         return false;
00470 }
00471 
00472 /********************** GetRi() ***********************/
00473 bool LSerie::getRi()                                            
00474 { 
00475   DWORD result;
00476                 GetCommModemStatus(hcom, &result);
00477                 if(result & MS_RING_ON)
00478                         return true;
00479                 else
00480                         return false;
00481 }
00482 
00483 
00484 /********************** GetCd() ***********************/
00485 bool LSerie::getCd()                                            
00486 { int err=0;
00487   DWORD result;
00488                 err = GetCommModemStatus(hcom, &result);
00489                 if(result & MS_RLSD_ON)
00490                         return true;
00491                 else
00492                         return false;
00493 }
00494 
00495 
00496 
00497 
00498 string LSerie::getErrorMsg()
00499 {
00500         LPVOID lpMsgBuf;
00501         string sErreur = "";
00502 
00503         if ( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
00504                                                         NULL, GetLastError(),
00505                                                         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
00506                                                         (LPTSTR) &lpMsgBuf, 0, NULL ))
00507         {
00508                 sErreur.assign((LPCTSTR)lpMsgBuf);
00509         }
00510 
00511         return sErreur;
00512 }
00513 
00514 
00515 bool LSerie::isConnect()
00516 {
00517         if(!getRi() && !getCd() && !getCd() && !getDtr() && !getCts())
00518     return false;
00519   return true;
00520 }
00521 
00522 std::list<unsigned int> LSerie::enumAvailablePorts()
00523 {
00524   std::list<unsigned int> portList;
00525   const HKEY HK = HKEY_LOCAL_MACHINE;
00526   const char* key = "HARDWARE\\DEVICEMAP\\SERIALCOMM";
00527 
00528   HKEY regData;
00529   RegOpenKeyEx(HK, key, 0, KEY_ALL_ACCESS, &regData);
00530 
00531   char* valName = new char[1024];
00532         char* value = new char[25];
00533         unsigned long NName = 1024;
00534         unsigned long NVal = 25;
00535 
00536         int n = 0;
00537   long Ret;
00538 
00539   while ((RegEnumValue(regData, n, (char *)valName, &NName, 0, 0, (unsigned char *)value, &NVal)) == ERROR_SUCCESS)
00540         {
00541     std::string temp = value;
00542     unsigned int iPort = 0;
00543     temp = temp.substr(3);
00544     
00545     valueOf(temp, iPort);
00546     portList.push_back(iPort);
00547 
00548     NName = 1024;
00549     NVal = 25;
00550 
00551     n++;
00552         }
00553   
00554   RegCloseKey(regData);
00555   delete(valName);
00556   delete(value);
00557   return portList;
00558 }