summaryrefslogtreecommitdiff
path: root/led/complex1/ledServer.h
diff options
context:
space:
mode:
Diffstat (limited to 'led/complex1/ledServer.h')
-rw-r--r--led/complex1/ledServer.h166
1 files changed, 166 insertions, 0 deletions
diff --git a/led/complex1/ledServer.h b/led/complex1/ledServer.h
new file mode 100644
index 0000000..35b7af1
--- /dev/null
+++ b/led/complex1/ledServer.h
@@ -0,0 +1,166 @@
+//
+// $Id$
+//
+
+#ifndef __LED_SERVER_h
+#define __LED_SERVER_h
+
+#include "MessageQueueT.h"
+
+#include <unistd.h>
+#include <time.h>
+
+#include "../led.h"
+
+namespace Examples {
+ class LEDServer {
+ private:
+ typedef enum {
+ StopLED,
+ StartLED,
+ ShutdownLED,
+ SetRate
+ } Discriminator_t;
+
+ typedef struct {
+ Discriminator_t discriminator;
+ union {
+ struct {
+ unsigned int on_period_in_milliseconds;
+ unsigned int off_period_in_milliseconds;
+ } Rate;
+ } Args;
+ } Message_t;
+
+ typedef OSWrapper::MessageQueueTemplate<Message_t> LEDQ_t;
+
+ LEDQ_t *mQueue;
+ pthread_t mThread;
+
+ static void *LEDServerThread( void *arg )
+ {
+ Examples::LEDServer *led = (Examples::LEDServer *)arg;
+
+ return led->ThreadBody();
+ }
+
+ public:
+ void *ThreadBody(void)
+ {
+ bool active = false;
+ unsigned int ledCount = 0;
+ unsigned int onPeriod = 0;
+ unsigned int offPeriod = 0;
+
+ Message_t m;
+ while ( 1 ) {
+ if ( mQueue->IsAvailable() ) {
+ mQueue->Read( &m );
+ switch ( m.discriminator ) {
+ case StartLED:
+ std::cerr << "StartLED" << std::endl;
+ active = true;
+ break;
+ case StopLED:
+ std::cerr << "StopLED" << std::endl;
+ active = false;
+ break;
+ case SetRate:
+ std::cerr << "SetRate: "
+ << "on=" << m.Args.Rate.on_period_in_milliseconds
+ << " off=" << m.Args.Rate.off_period_in_milliseconds
+ << std::endl;
+
+ onPeriod = m.Args.Rate.on_period_in_milliseconds;
+ offPeriod = m.Args.Rate.off_period_in_milliseconds;
+ break;
+ case ShutdownLED:
+ std::cerr << "Shutdown of LED Server requested" << std::endl;
+ goto thread_exit;
+ break;
+ default:
+ break;
+ }
+ }
+ if ( active ) {
+ struct timespec ts;
+ unsigned int p;
+
+ if ( (++ledCount % 2) == 1 ) {
+ LED_ON();
+ p = onPeriod;
+ } else {
+ LED_OFF();
+ p = offPeriod;
+ }
+
+ p = (p) ? p : 500;
+ ts.tv_sec = (p / 1000);
+ ts.tv_nsec = (p * 1000000) % 1000000000;
+ nanosleep( &ts, NULL );
+ } else {
+ sleep(1);
+ }
+ }
+ thread_exit:
+ return NULL;
+ }
+
+ public:
+ LEDServer()
+ {
+ int status;
+
+ mQueue = new LEDQ_t( std::string("LEDQ"), (unsigned int) 10 );
+ status =
+ pthread_create( &mThread, NULL, LEDServerThread, (void *)this );
+ if ( status ) {
+ std::cerr << "LEDServer: pthread_create failed "
+ << status << std::endl;
+ }
+ }
+
+ ~LEDServer()
+ {
+ Message_t msg;
+
+ msg.discriminator = ShutdownLED;
+ mQueue->Write( &msg );
+ sleep(1);
+
+ delete mQueue;
+ }
+
+ void start( void )
+ {
+ Message_t msg;
+
+ msg.discriminator = StartLED;
+ mQueue->Write( &msg );
+ }
+
+ void stop( void )
+ {
+ Message_t msg;
+
+ msg.discriminator = StopLED;
+ mQueue->Write( &msg );
+ }
+
+ void setPeriod( unsigned int on, unsigned int off )
+ {
+ Message_t msg;
+
+ if ( !on || !off ) {
+ std::cerr << "setPeriod: 0 period is not allowed" << std::endl;
+ return;
+ }
+ msg.discriminator = SetRate;
+ msg.Args.Rate.on_period_in_milliseconds = on;
+ msg.Args.Rate.off_period_in_milliseconds = off;
+ mQueue->Write( &msg );
+ }
+ };
+}
+#endif
+