<commit_before>///////////////////////////////////////////////////////////////////////////////
// FILE:          SerialManager.cpp
// PROJECT:       Micro-Manager
// SUBSYSTEM:     DeviceAdapters
//-----------------------------------------------------------------------------
// DESCRIPTION:   Serial port device adapter
//
// COPYRIGHT:     University of California, San Francisco, 2010
// LICENSE:       This file is distributed under the BSD license.
//                License text is included with the source distribution.
//
//                This file is distributed in the hope that it will be useful,
//                but WITHOUT ANY WARRANTY; without even the implied warranty
//                of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
//                IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//                CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//                INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES.
//
// AUTHOR:        <NAME> - <NAME> - use CSerial class
//                <NAME> - <NAME> - use boost, also simplify handling of terminators
//
// CVS:           $Id$
//

#ifdef WIN32
   #define WIN32_LEAN_AND_MEAN
   #include <windows.h>
   #define snprintf _snprintf 
#endif

#ifdef __APPLE__    

#define BOOST_ASIO_DISABLE_KQUEUE  // suggested to fix "Operation not supported" on OS X
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/serial/IOSerialKeys.h>
#if defined(MAC_OS_X_VERSION_10_3) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3)
   #include <IOKit/serial/ioss.h>
#endif
#include <IOKit/IOBSD.h>
#endif

#ifdef linux
#include <dirent.h>
#endif

#include "../../MMDevice/ModuleInterface.h"
#include "../../MMDevice/DeviceUtils.h"
#include "SerialManager.h"
#include <sstream>
#include <cstdio>

#include <deque> 
#include <iostream> 


#include <boost/bind.hpp> 
#include <boost/asio.hpp> 
#include <boost/asio/serial_port.hpp> 
#include <boost/thread.hpp> 
#include <boost/lexical_cast.hpp> 
#include <boost/date_time/posix_time/posix_time_types.hpp> 


// serial device implementation class
#include "AsioClient.h"


SerialManager g_serialManager;

std::vector<std::string> g_BlackListedPorts;
std::vector<std::string> g_PortList;
time_t g_PortListLastUpdated = 0;

const char* g_StopBits_1 = "1";
const char* g_StopBits_1_5 = "1.5";
const char* g_StopBits_2 = "2";

const char* g_Baud_110 = "110";
const char* g_Baud_300 = "300";
const char* g_Baud_600 = "600";
const char* g_Baud_1200 = "1200";
const char* g_Baud_2400 = "2400";
const char* g_Baud_4800 = "4800";
const char* g_Baud_9600 = "9600";
const char* g_Baud_14400 = "14400";
const char* g_Baud_19200 = "19200";
const char* g_Baud_57600 = "57600";
const char* g_Baud_115200 = "115200";
const char* g_Baud_128000 = "128000";
const char* g_Baud_230400 = "230400";
const char* g_Baud_460800 = "460800";
const char* g_Baud_500000 = "500000";
const char* g_Baud_576000 = "576000";
const char* g_Baud_921600 = "921600";

const char* g_Handshaking_Off = "Off";
const char* g_Handshaking_Hardware = "Hardware";
const char* g_Handshaking_Software = "Software";

const char* g_Parity_None = "None";
const char* g_Parity_Odd = "Odd";
const char* g_Parity_Even = "Even";
const char* g_Parity_Mark = "Mark";
const char* g_Parity_Space = "Space";

#ifdef WIN32
#include <time.h>
   BOOL APIENTRY DllMain( HANDLE /*hModule*/, 
                          DWORD  ul_reason_for_call, 
                          LPVOID /*lpReserved*/
		   			 )
   {
   	switch (ul_reason_for_call)
   	{
   	case DLL_PROCESS_ATTACH:

   	case DLL_THREAD_ATTACH:
   	case DLL_THREAD_DETACH:
   	case DLL_PROCESS_DETACH:
   		break;
   	}
       return TRUE;
   }
#endif

/*
 * Tests whether given serial port can be used by opening it
 */
bool SerialPortLister::portAccessible(const char* portName)
{
   try
   {
      boost::asio::io_service service;
      boost::asio::serial_port sp(service, portName);

      if (sp.is_open()) {
         sp.close();
         return true;
      }
   }
   catch( std::exception& )
   {
      
      return false;
   }

   return false;                                                             
}


#ifdef WIN32
const int MaxBuf = 100000;
typedef struct 
	{
		char buffer[MaxBuf];
} B100000;
#endif




void SerialPortLister::ListPorts(std::vector<std::string> &availablePorts)
{
#ifdef WIN32

   availablePorts.clear();
   std::auto_ptr<B100000> allDeviceNames (new B100000());

   // on Windows the serial ports are devices that begin with "COM"
   int ret = QueryDosDevice( 0, allDeviceNames->buffer, MaxBuf);
   if( 0!= ret)
   {
      for( int ii = 0; ii < ret; ++ii)
      {
         if ( 0 == allDeviceNames->buffer[ii])
            allDeviceNames->buffer[ii] = ' ';
      }
      std::string all(allDeviceNames->buffer, ret);
      std::vector<std::string> tokens;
      CDeviceUtils::Tokenize(all, tokens, " ");
      for( std::vector<std::string>::iterator jj = tokens.begin(); jj != tokens.end(); ++jj)
      {
         if( 0 == jj->substr(0,3).compare("COM"))
            availablePorts.push_back(*jj);
      }
      
   }
#endif // WIN32

#ifdef linux 
   // Look for /dev files with correct signature in their name 
   DIR* pdir = opendir("/dev");
   struct dirent *pent;
   if (pdir) {
      while (pent = readdir(pdir)) {
         if ( (strstr(pent->d_name, "ttyS") != 0) || (strstr(pent->d_name, "ttyUSB") != 0) )  {
            std::string p = ("/dev/");
            p.append(pent->d_name);
            if (portAccessible(p.c_str()))
               availablePorts.push_back(p.c_str());
         }
      }
   }
#endif // linux <commit_msg>Patch from <NAME> to make Arduino UNO port appear under Linux<commit_after>///////////////////////////////////////////////////////////////////////////////
// FILE:          SerialManager.cpp
// PROJECT:       Micro-Manager
// SUBSYSTEM:     DeviceAdapters
//-----------------------------------------------------------------------------
// DESCRIPTION:   Serial port device adapter
//
// COPYRIGHT:     University of California, San Francisco, 2010
// LICENSE:       This file is distributed under the BSD license.
//                License text is included with the source distribution.
//
//                This file is distributed in the hope that it will be useful,
//                but WITHOUT ANY WARRANTY; without even the implied warranty
//                of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
//                IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//                CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//                INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES.
//
// AUTHOR:        <NAME> - <NAME> - use CSerial class
//                <NAME> - <NAME> - use boost, also simplify handling of terminators
//
// CVS:           $Id$
//

#ifdef WIN32
   #define WIN32_LEAN_AND_MEAN
   #include <windows.h>
   #define snprintf _snprintf 
#endif

#ifdef __APPLE__    

#define BOOST_ASIO_DISABLE_KQUEUE  // suggested to fix "Operation not supported" on OS X
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/serial/IOSerialKeys.h>
#if defined(MAC_OS_X_VERSION_10_3) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3)
   #include <IOKit/serial/ioss.h>
#endif
#include <IOKit/IOBSD.h>
#endif

#ifdef linux
#include <dirent.h>
#endif

#include "../../MMDevice/ModuleInterface.h"
#include "../../MMDevice/DeviceUtils.h"
#include "SerialManager.h"
#include <sstream>
#include <cstdio>

#include <deque> 
#include <iostream> 


#include <boost/bind.hpp> 
#include <boost/asio.hpp> 
#include <boost/asio/serial_port.hpp> 
#include <boost/thread.hpp> 
#include <boost/lexical_cast.hpp> 
#include <boost/date_time/posix_time/posix_time_types.hpp> 


// serial device implementation class
#include "AsioClient.h"


SerialManager g_serialManager;

std::vector<std::string> g_BlackListedPorts;
std::vector<std::string> g_PortList;
time_t g_PortListLastUpdated = 0;

const char* g_StopBits_1 = "1";
const char* g_StopBits_1_5 = "1.5";
const char* g_StopBits_2 = "2";

const char* g_Baud_110 = "110";
const char* g_Baud_300 = "300";
const char* g_Baud_600 = "600";
const char* g_Baud_1200 = "1200";
const char* g_Baud_2400 = "2400";
const char* g_Baud_4800 = "4800";
const char* g_Baud_9600 = "9600";
const char* g_Baud_14400 = "14400";
const char* g_Baud_19200 = "19200";
const char* g_Baud_57600 = "57600";
const char* g_Baud_115200 = "115200";
const char* g_Baud_128000 = "128000";
const char* g_Baud_230400 = "230400";
const char* g_Baud_460800 = "460800";
const char* g_Baud_500000 = "500000";
const char* g_Baud_576000 = "576000";
const char* g_Baud_921600 = "921600";

const char* g_Handshaking_Off = "Off";
const char* g_Handshaking_Hardware = "Hardware";
const char* g_Handshaking_Software = "Software";

const char* g_Parity_None = "None";
const char* g_Parity_Odd = "Odd";
const char* g_Parity_Even = "Even";
const char* g_Parity_Mark = "Mark";
const char* g_Parity_Space = "Space";

#ifdef WIN32
#include <time.h>
   BOOL APIENTRY DllMain( HANDLE /*hModule*/, 
                          DWORD  ul_reason_for_call, 
                          LPVOID /*lpReserved*/
		   			 )
   {
   	switch (ul_reason_for_call)
   	{
   	case DLL_PROCESS_ATTACH:

   	case DLL_THREAD_ATTACH:
   	case DLL_THREAD_DETACH:
   	case DLL_PROCESS_DETACH:
   		break;
   	}
       return TRUE;
   }
#endif

/*
 * Tests whether given serial port can be used by opening it
 */
bool SerialPortLister::portAccessible(const char* portName)
{
   try
   {
      boost::asio::io_service service;
      boost::asio::serial_port sp(service, portName);

      if (sp.is_open()) {
         sp.close();
         return true;
      }
   }
   catch( std::exception& )
   {
      
      return false;
   }

   return false;                                                             
}


#ifdef WIN32
const int MaxBuf = 100000;
typedef struct 
	{
		char buffer[MaxBuf];
} B100000;
#endif




void SerialPortLister::ListPorts(std::vector<std::string> &availablePorts)
{
#ifdef WIN32

   availablePorts.clear();
   std::auto_ptr<B100000> allDeviceNames (new B100000());

   // on Windows the serial ports are devices that begin with "COM"
   int ret = QueryDosDevice( 0, allDeviceNames->buffer, MaxBuf);
   if( 0!= ret)
   {
      for( int ii = 0; ii < ret; ++ii)
      {
         if ( 0 == allDeviceNames->buffer[ii])
            allDeviceNames->buffer[ii] = ' ';
      }
      std::string all(allDeviceNames->buffer, ret);
      std::vector<std::string> tokens;
      CDeviceUtils::Tokenize(all, tokens, " ");
      for( std::vector<std::string>::iterator jj = tokens.begin(); jj != tokens.end(); ++jj)
      {
         if( 0 == jj->substr(0,3).compare("COM"))
            availablePorts.push_back(*jj);
      }
      
   }
#endif // WIN32

#ifdef linux 
   // Look for /dev files with correct signature 
   DIR* pdir = opendir("/dev");
   struct dirent *pent;
   if (pdir) {
      while (pent = readdir(pdir)) {
         if ( (strstr(pent->d_name, "ttyS") != 0) || 
               (strstr(pent->d_name, "ttyUSB") != 0)  || 
               (strstr(pent->d_name, "ttyACM") != 0))  
         {
            std::string p = ("/dev/");
            p.append(pent->d_name);
            if (portAccessible(p.c_str()))
               availablePorts.push_back(p.c_str());
         }
      }
   }
#endif // linux 
{'fraction_non_alphanumeric': 0.1504424778761062, 'fraction_numerical': 0.04004205730307544, 'mean_word_length': 2.516327788046827, 'pattern_counts': {'":': 0, '<': 62, '<?xml version=': 0, '>': 79, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6879725', 'n_tokens_mistral': 4182, 'n_tokens_neox': 3769, 'n_words': 952}