AlarmNotifications
PANDA Slow Control Alarm Daemon
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
flashlight.cpp
Go to the documentation of this file.
1 
34 #include "flashlight.h"
35 
36 #include <fcntl.h>
37 #include <stdexcept>
38 
39 #include "alarmconfiguration.h"
40 #include "exceptionhandler.h"
41 
42 using namespace AlarmNotifications;
43 
45 {
46  static FlashLight global_instance;
47  return global_instance;
48 }
49 
50 
52  : _deviceNode ( AlarmConfiguration::instance().getFlashLightRelaisDeviceNode() ),
53  _fd ( -1 ),
54  _fdOpen ( false )
55 {
56 }
57 
59 {
60  if ( _fdOpen )
62 }
63 
65 {
66  try{
68  }
69  catch ( std::exception& e )
70  {
71  ExceptionHandler ( e, "switching on the flash light." );
72  }
73  catch ( ... )
74  {
75  ExceptionHandler ( "switching on the flash light." );
76  }
77 }
78 
80 {
81  try {
83  }
84  catch ( std::exception& e )
85  {
86  ExceptionHandler ( e, "switching off the flash light." );
87  }
88  catch ( ... )
89  {
90  ExceptionHandler ( "switching off the flash light." );
91  }
92 }
93 
94 void FlashLight::switchInternal ( const bool lightSwitch )
95 {
96  const deviceCommand command = createCommand ( lightSwitch );
97  boost::lock_guard<boost::mutex> concurrencylock ( _serialLineMutex );
98 
101  writeSerialInteface ( command );
103 }
104 
106 {
107  deviceCommand command;
108  // Command: Set relais
109  command.push_back ( '\xff' );
110  // Selected relais: number one (device has only one)
111  command.push_back ( '\x01' );
112  // Select action:
113  if ( lightSwitch )
114  command.push_back ( '\x01' );
115  else
116  command.push_back ( '\x00' );
117  return command;
118 }
119 
121 {
122  _fd = open ( _deviceNode.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK );
123  if ( _fd < 0 )
124  throw std::runtime_error ( "Cannot open serial interface for flashlight." );
125  _fdOpen = true;
126 }
127 
129 {
130  if ( !_fdOpen )
131  throw std::logic_error ( "configureSerialInterface() called on closed interface." );
132  termios serialConfig;
133  const int getattr_result = tcgetattr ( _fd, &serialConfig );
134  if ( getattr_result < 0 )
135  throw std::runtime_error ( "Error while reading configuration of serial interface." );
136 
137  // Return immediately on read if no bytes are available
138  serialConfig.c_cc[VMIN] = 0;
139  serialConfig.c_cc[VTIME] = 0;
140 
141  // Ignore modem control lines
142  serialConfig.c_cflag |= CREAD | CLOCAL;
143 
144  // Switch off software handshake
145  serialConfig.c_iflag &= ~IXON & ~IXOFF;
146 
147  // Set 8bit character size
148  serialConfig.c_cflag &= ~CSIZE;
149  serialConfig.c_cflag |= CS8;
150 
151  // Set parity to none
152  serialConfig.c_cflag &= ~PARENB & ~PARODD;
153  serialConfig.c_iflag |= IGNPAR;
154 
155  // Set number of stop bits to 1
156  serialConfig.c_cflag &= ~CSTOPB;
157 
158  // Disable hardware handshake
159  serialConfig.c_cflag &= ~CRTSCTS;
160 
161  // Set baud rate
162  const int ispeed_result = cfsetispeed ( &serialConfig, deviceBaudRate );
163  if ( ispeed_result < 0 )
164  throw std::runtime_error ( "Cannot set input baud rate." );
165  const int ospeed_result = cfsetospeed ( &serialConfig, deviceBaudRate );
166  if ( ospeed_result < 0 )
167  throw std::runtime_error ( "Cannot set input baud rate." );
168 
169  //Write new configuration to interface
170  const int setattr_result = tcsetattr ( _fd, TCSANOW, &serialConfig );
171  if ( setattr_result < 0 )
172  throw std::runtime_error ( "Error while writing configuration of serial interface." );
173 }
174 
176 {
177  if ( !_fdOpen )
178  throw std::logic_error ( "writeSerialInterface() called on closed interface." );
179  const long unsigned int numBytes = command.size();
180  uint8_t* buffer = nullptr;
181  try
182  {
183  // Create a local character buffer to be passed to write()
184  buffer = new uint8_t[numBytes+1]; // One byte safety, just to be sure
185  if ( buffer == nullptr )
186  throw std::bad_alloc(); // If new returns a null pointer, there is not enough memory available
187  // Set all bytes in the buffer to zero.
188  memset ( buffer, 0, numBytes+1 );
189  // Copy string content into buffer
190  std::copy ( command.begin(), command.end(), buffer );
191  // Write buffer to serial interface
192  long int bytesWritten = -1;
193  do
194  {
195  bytesWritten = write ( _fd, buffer, numBytes );
196  }
197  while ( ( bytesWritten < 0 && EAGAIN == errno ) ); // Repeat if error code EAGAIN occurs
198 
199  if ( bytesWritten < 0 )
200  throw std::runtime_error ( "An error occured while writing to the serial interface" );
201  if ( ( long unsigned int ) ( bytesWritten ) < numBytes )
202  throw std::runtime_error ( "Could not write all bytes to serial interface" );
203 
204  delete[] buffer;
205  }
206  catch ( ... )
207  {
208  delete[] buffer;
209  }
210 }
211 
213 {
214  _fdOpen = false;
215  close ( _fd );
216  _fd = -1;
217 }
void configureSerialInterface()
Set options of serial interface for USB relais.
Definition: flashlight.cpp:128
int _fd
File descriptor.
Definition: flashlight.h:81
void switchInternal(const bool lightSwitch)
Internal routine to switch relais on or off.
Definition: flashlight.cpp:94
static void switchOff() noexcept
Switch off red alarm flash light.
Definition: flashlight.cpp:79
Control USB relais for red alarm flash light.
boost::mutex _serialLineMutex
Mutex to protect device access.
Definition: flashlight.h:75
const std::string _deviceNode
Path to the device file.
Definition: flashlight.h:69
static const unsigned int deviceBaudRate
Constant for baud rate.
Definition: flashlight.h:93
static void switchOn() noexcept
Switch on red alarm flash light.
Definition: flashlight.cpp:64
void closeSerialInterface()
Close the device handle.
Definition: flashlight.cpp:212
std::vector< uint8_t > deviceCommand
Type for storing commands to the device.
Definition: flashlight.h:62
Namespace for Alarm Notifications application.
void writeSerialInteface(const deviceCommand command)
Write command sequence to the USB relais.
Definition: flashlight.cpp:175
bool _fdOpen
File descriptor use flag.
Definition: flashlight.h:87
#define noexcept
Allow using the noexcept keyword with GCC < 4.6.
Definition: oldgcccompat.h:52
void openSerialInterface()
Open serial interface.
Definition: flashlight.cpp:120
static deviceCommand createCommand(const bool lightSwitch)
Assemble command sequence.
Definition: flashlight.cpp:105
void ExceptionHandler(std::exception &e, std::string location, const bool quit=false) noexcept
Generic exception handler for known exceptions.
static FlashLight & instance() noexcept
Get singleton instance.
Definition: flashlight.cpp:44
Generic functions for exception handling.
Singleton to read and change the configuration of this application.
Controller for USB relais of red alarm flash light.
Definition: flashlight.h:55
Configuration of the AlarmNotifications application.