00001
00034 #include "flashlight.h"
00035
00036 #include <fcntl.h>
00037 #include <stdexcept>
00038
00039 #include "alarmconfiguration.h"
00040 #include "exceptionhandler.h"
00041
00042 using namespace AlarmNotifications;
00043
00044 FlashLight& FlashLight::instance() noexcept
00045 {
00046 static FlashLight global_instance;
00047 return global_instance;
00048 }
00049
00050
00051 FlashLight::FlashLight()
00052 : _deviceNode ( AlarmConfiguration::instance().getFlashLightRelaisDeviceNode() ),
00053 _fd ( -1 ),
00054 _fdOpen ( false )
00055 {
00056 }
00057
00058 FlashLight::~FlashLight()
00059 {
00060 if ( _fdOpen )
00061 closeSerialInterface();
00062 }
00063
00064 void FlashLight::switchOn() noexcept
00065 {
00066 try{
00067 FlashLight::instance().switchInternal ( true );
00068 }
00069 catch ( std::exception& e )
00070 {
00071 ExceptionHandler ( e, "switching on the flash light." );
00072 }
00073 catch ( ... )
00074 {
00075 ExceptionHandler ( "switching on the flash light." );
00076 }
00077 }
00078
00079 void FlashLight::switchOff() noexcept
00080 {
00081 try {
00082 FlashLight::instance().switchInternal ( false );
00083 }
00084 catch ( std::exception& e )
00085 {
00086 ExceptionHandler ( e, "switching off the flash light." );
00087 }
00088 catch ( ... )
00089 {
00090 ExceptionHandler ( "switching off the flash light." );
00091 }
00092 }
00093
00094 void FlashLight::switchInternal ( const bool lightSwitch )
00095 {
00096 const deviceCommand command = createCommand ( lightSwitch );
00097 boost::lock_guard<boost::mutex> concurrencylock ( _serialLineMutex );
00098
00099 openSerialInterface();
00100 configureSerialInterface();
00101 writeSerialInteface ( command );
00102 closeSerialInterface();
00103 }
00104
00105 FlashLight::deviceCommand FlashLight::createCommand ( const bool lightSwitch )
00106 {
00107 deviceCommand command;
00108
00109 command.push_back ( '\xff' );
00110
00111 command.push_back ( '\x01' );
00112
00113 if ( lightSwitch )
00114 command.push_back ( '\x01' );
00115 else
00116 command.push_back ( '\x00' );
00117 return command;
00118 }
00119
00120 void FlashLight::openSerialInterface()
00121 {
00122 _fd = open ( _deviceNode.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK );
00123 if ( _fd < 0 )
00124 throw std::runtime_error ( "Cannot open serial interface for flashlight." );
00125 _fdOpen = true;
00126 }
00127
00128 void FlashLight::configureSerialInterface()
00129 {
00130 if ( !_fdOpen )
00131 throw std::logic_error ( "configureSerialInterface() called on closed interface." );
00132 termios serialConfig;
00133 const int getattr_result = tcgetattr ( _fd, &serialConfig );
00134 if ( getattr_result < 0 )
00135 throw std::runtime_error ( "Error while reading configuration of serial interface." );
00136
00137
00138 serialConfig.c_cc[VMIN] = 0;
00139 serialConfig.c_cc[VTIME] = 0;
00140
00141
00142 serialConfig.c_cflag |= CREAD | CLOCAL;
00143
00144
00145 serialConfig.c_iflag &= ~IXON & ~IXOFF;
00146
00147
00148 serialConfig.c_cflag &= ~CSIZE;
00149 serialConfig.c_cflag |= CS8;
00150
00151
00152 serialConfig.c_cflag &= ~PARENB & ~PARODD;
00153 serialConfig.c_iflag |= IGNPAR;
00154
00155
00156 serialConfig.c_cflag &= ~CSTOPB;
00157
00158
00159 serialConfig.c_cflag &= ~CRTSCTS;
00160
00161
00162 const int ispeed_result = cfsetispeed ( &serialConfig, deviceBaudRate );
00163 if ( ispeed_result < 0 )
00164 throw std::runtime_error ( "Cannot set input baud rate." );
00165 const int ospeed_result = cfsetospeed ( &serialConfig, deviceBaudRate );
00166 if ( ospeed_result < 0 )
00167 throw std::runtime_error ( "Cannot set input baud rate." );
00168
00169
00170 const int setattr_result = tcsetattr ( _fd, TCSANOW, &serialConfig );
00171 if ( setattr_result < 0 )
00172 throw std::runtime_error ( "Error while writing configuration of serial interface." );
00173 }
00174
00175 void FlashLight::writeSerialInteface ( const FlashLight::deviceCommand command )
00176 {
00177 if ( !_fdOpen )
00178 throw std::logic_error ( "writeSerialInterface() called on closed interface." );
00179 const long unsigned int numBytes = command.size();
00180 uint8_t* buffer = nullptr;
00181 try
00182 {
00183
00184 buffer = new uint8_t[numBytes+1];
00185 if ( buffer == nullptr )
00186 throw std::bad_alloc();
00187
00188 memset ( buffer, 0, numBytes+1 );
00189
00190 std::copy ( command.begin(), command.end(), buffer );
00191
00192 long int bytesWritten = -1;
00193 do
00194 {
00195 bytesWritten = write ( _fd, buffer, numBytes );
00196 }
00197 while ( ( bytesWritten < 0 && EAGAIN == errno ) );
00198
00199 if ( bytesWritten < 0 )
00200 throw std::runtime_error ( "An error occured while writing to the serial interface" );
00201 if ( ( long unsigned int ) ( bytesWritten ) < numBytes )
00202 throw std::runtime_error ( "Could not write all bytes to serial interface" );
00203
00204 delete[] buffer;
00205 }
00206 catch ( ... )
00207 {
00208 delete[] buffer;
00209 }
00210 }
00211
00212 void FlashLight::closeSerialInterface()
00213 {
00214 _fdOpen = false;
00215 close ( _fd );
00216 _fd = -1;
00217 }