driver.h
00001 /*
00002  *  Player - One Hell of a Robot Server
00003  *  Copyright (C) 2000
00004  *     Brian Gerkey, Kasper Stoy, Richard Vaughan, & Andrew Howard
00005  *
00006  *
00007  *  This program is free software; you can redistribute it and/or modify
00008  *  it under the terms of the GNU General Public License as published by
00009  *  the Free Software Foundation; either version 2 of the License, or
00010  *  (at your option) any later version.
00011  *
00012  *  This program is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *  GNU General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU General Public License
00018  *  along with this program; if not, write to the Free Software
00019  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  */
00022 /********************************************************************
00023  *
00024  *  This library is free software; you can redistribute it and/or
00025  *  modify it under the terms of the GNU Lesser General Public
00026  *  License as published by the Free Software Foundation; either
00027  *  version 2.1 of the License, or (at your option) any later version.
00028  *
00029  *  This library is distributed in the hope that it will be useful,
00030  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00031  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00032  *  Lesser General Public License for more details.
00033  *
00034  *  You should have received a copy of the GNU Lesser General Public
00035  *  License along with this library; if not, write to the Free Software
00036  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00037  *
00038  ********************************************************************/
00039 
00040 /*
00041  * $Id: driver.h 9049 2011-05-24 01:58:11Z jpgr87 $
00042  *
00043  *  The virtual class from which all driver classes inherit.  this
00044  *  defines the API that all drivers must implement.
00045  */
00046 
00047 #ifndef _DRIVER_H
00048 #define _DRIVER_H
00049 
00050 #if defined (WIN32)
00051   #if defined (PLAYER_STATIC)
00052     #define PLAYERCORE_EXPORT
00053   #elif defined (playercore_EXPORTS)
00054     #define PLAYERCORE_EXPORT    __declspec (dllexport)
00055   #else
00056     #define PLAYERCORE_EXPORT    __declspec (dllimport)
00057   #endif
00058 #else
00059   #define PLAYERCORE_EXPORT
00060 #endif
00061 
00062 #include <pthread.h>
00063 
00064 #include <libplayercommon/playercommon.h>
00065 #include <libplayercore/message.h>
00066 #include <libplayerinterface/player.h>
00067 #include <libplayercore/property.h>
00068 
00069 //using namespace std;
00070 
00086 #define HANDLE_CAPABILITY_REQUEST(device_addr, queue, hdr, data, cap_type, cap_subtype) \
00087   if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ, PLAYER_CAPABILITIES_REQ, device_addr)) \
00088   { \
00089     player_capabilities_req_t & cap_req = * reinterpret_cast<player_capabilities_req_t *> (data);\
00090     if (cap_req.type == cap_type && cap_req.subtype == cap_subtype) \
00091     { \
00092       Publish(device_addr, queue, PLAYER_MSGTYPE_RESP_ACK, PLAYER_CAPABILITIES_REQ); \
00093       return 0; \
00094     } \
00095   }
00096 
00097 
00098 // Forward declarations
00099 class ConfigFile;
00100 
00108 class PLAYERCORE_EXPORT Driver
00109 {
00110   private:
00111     /* @brief Last error value; useful for returning error codes from
00112     constructors. */
00113     int error;
00114 
00115     PropertyBag propertyBag;
00116 
00118         int subscriptions;
00119   public:
00120     bool HasSubscriptions();
00121 
00122   protected:
00123 
00129     int AddInterface(player_devaddr_t addr);
00130 
00141     int AddInterface(player_devaddr_t *addr, ConfigFile * cf, int section, int code, const char * key = NULL);
00142 
00143 
00145     void SetError(int code) {this->error = code;}
00146 
00156     virtual bool Wait(double TimeOut=0.0);
00157 
00159     int AddFileWatch(int fd, bool ReadWatch = true, bool WriteWatch = false, bool ExceptWatch = true);
00160 
00162     int RemoveFileWatch(int fd, bool ReadWatch = true, bool WriteWatch = false, bool ExceptWatch = true);
00163 
00164 
00165   private:
00168     pthread_mutex_t accessMutex;
00170     pthread_mutex_t subscriptionMutex;
00171   protected:
00174      virtual void Lock(void);
00176     virtual void Unlock(void);
00177 
00179      virtual void SubscriptionLock(void);
00181     virtual void SubscriptionUnlock(void);
00182 
00186     virtual void TestCancel() {};
00187 
00188 
00189   public:
00195     QueuePointer ret_queue;
00196 
00211     virtual void Publish(player_devaddr_t addr,
00212                  QueuePointer &queue,
00213                  uint8_t type,
00214                  uint8_t subtype,
00215                  void* src=NULL,
00216                  size_t deprecated=0,
00217                  double* timestamp=NULL,
00218                  bool copy=true);
00219 
00233      virtual void Publish(player_devaddr_t addr,
00234                   uint8_t type,
00235                   uint8_t subtype,
00236                   void* src=NULL,
00237                   size_t deprecated=0,
00238                   double* timestamp=NULL,
00239                   bool copy=true);
00240 
00241 
00242 
00251     virtual void Publish(QueuePointer &queue,
00252                  player_msghdr_t* hdr,
00253                  void* src,
00254                  bool copy = true);
00255 
00263     virtual void Publish(player_msghdr_t* hdr,
00264                  void* src,
00265                  bool copy = true);
00266 
00267 
00269     player_devaddr_t device_addr;
00270 
00273     int entries;
00274 
00282     bool alwayson;
00283 
00285     QueuePointer InQueue;
00286 
00294     Driver(ConfigFile *cf,
00295            int section,
00296            bool overwrite_cmds,
00297            size_t queue_maxlen,
00298            int interf);
00299 
00307     Driver(ConfigFile *cf,
00308            int section,
00309            bool overwrite_cmds = true,
00310            size_t queue_maxlen = PLAYER_MSGQUEUE_DEFAULT_MAXLEN);
00311 
00313     virtual ~Driver();
00314 
00317     int GetError() { return(this->error); }
00318 
00328     virtual int Subscribe(player_devaddr_t addr);
00329 
00343     virtual int Subscribe(QueuePointer &queue, player_devaddr_t addr) {return 1;};
00344 
00354     virtual int Unsubscribe(player_devaddr_t addr);
00355 
00369     virtual int Unsubscribe(QueuePointer &queue, player_devaddr_t addr) {return 1;};
00370 
00377     virtual int Terminate();
00378 
00379 
00386     virtual int Setup() {return 0;};
00387 
00393     virtual int Shutdown() {return 0;};
00394 
00402     void ProcessMessages(int maxmsgs);
00403 
00408     void ProcessMessages(void);
00409 
00419     virtual int ProcessMessage(QueuePointer &resp_queue, player_msghdr * hdr,
00420                                void * data);
00421 
00423     virtual void Update()
00424     {
00425         this->ProcessMessages();
00426     }
00427 
00435     virtual int ProcessInternalMessages(QueuePointer& resp_queue,
00436                                         player_msghdr * hdr,
00437                                         void * data);
00438 
00446     virtual bool RegisterProperty(const char *key, 
00447                                   Property *property, 
00448                                   ConfigFile* cf, 
00449                                   int section);
00450 
00458     virtual bool RegisterProperty(Property *property, 
00459                                   ConfigFile* cf, 
00460                                   int section);
00461 };
00462 
00463 typedef enum player_thread_state
00464 {
00465         PLAYER_THREAD_STATE_STOPPED,
00466         PLAYER_THREAD_STATE_RUNNING,
00467         PLAYER_THREAD_STATE_STOPPING,
00468         PLAYER_THREAD_STATE_RESTARTING
00469 } player_thread_state_t;
00470 
00471 class PLAYERCORE_EXPORT PlayerBarrier
00472 {
00473 public:
00474         PlayerBarrier()
00475         {
00476                 pthread_mutex_init(&barrierMutex,NULL);
00477                 pthread_cond_init(&barrierCond,NULL);
00478                 barrierValue = 0;
00479         }
00480         ~PlayerBarrier()
00481         {
00482                 pthread_mutex_destroy(&barrierMutex);
00483                 pthread_cond_destroy(&barrierCond);
00484         };
00485 
00486         int SetValue(int Value)
00487         {
00488                 return barrierValue = Value;
00489         };
00490 
00491         int Wait()
00492         {
00493                 pthread_mutex_lock(&barrierMutex);
00494                 assert(barrierValue);
00495                 if (--barrierValue)
00496                         pthread_cond_wait(&barrierCond,&barrierMutex);
00497                 else
00498                         pthread_cond_broadcast(&barrierCond);
00499                 pthread_mutex_unlock(&barrierMutex);
00500                 return 0;
00501         };
00502 private:
00505     pthread_mutex_t barrierMutex;
00506 
00507     int barrierValue;
00508 
00509     pthread_cond_t barrierCond;
00510 
00511 };
00512 
00513 
00514 
00552 class PLAYERCORE_EXPORT ThreadedDriver : public Driver
00553 {
00554   protected:
00555 
00556     /* @brief Start the driver thread
00557 
00558     This method is usually called from the overloaded Setup() method to
00559     create the driver thread.  This will call Main(). */
00560     virtual void StartThread(void);
00561 
00566     virtual void StopThread(void);
00567 
00570     static void* DummyMain(void *driver);
00571 
00574     static void DummyMainQuit(void *driver);
00575 
00576   private:
00580     pthread_t driverthread;
00581 
00584     player_thread_state_t ThreadState;
00585     bool SetupSuccessful;
00586 
00588     PlayerBarrier SetupBarrier;
00589 
00590   protected:
00594     void TestCancel();
00595 
00596 
00597   public:
00598 
00605          ThreadedDriver(ConfigFile *cf,
00606                         int section,
00607                         bool overwrite_cmds,
00608                         size_t queue_maxlen,
00609                         int interface_);
00610 
00618     ThreadedDriver(ConfigFile *cf,
00619            int section,
00620            bool overwrite_cmds = true,
00621            size_t queue_maxlen = PLAYER_MSGQUEUE_DEFAULT_MAXLEN);
00622 
00624     virtual ~ThreadedDriver();
00625 
00632     virtual int Setup();
00633 
00640     virtual int Shutdown();
00641 
00648     virtual int Terminate();
00649 
00655     virtual void Main(void) = 0;
00656 
00658     virtual int MainSetup(void) {return 0;};
00659 
00664     virtual void MainQuit(void) {};
00665 
00675     bool Wait(double TimeOut=0.0);
00676 
00677     virtual void Update()
00678     {};
00679 
00680 };
00681 
00682 
00683 #endif