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 8004 2009-07-13 14:03:44Z thjc $ 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_CAPABILTIES_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_CAPABILTIES_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 00138 int AddInterface(player_devaddr_t *addr, ConfigFile * cf, int section, int code, const char * key = NULL); 00139 00140 00142 void SetError(int code) {this->error = code;} 00143 00153 virtual bool Wait(double TimeOut=0.0); 00154 00156 int AddFileWatch(int fd, bool ReadWatch = true, bool WriteWatch = false, bool ExceptWatch = true); 00157 00159 int RemoveFileWatch(int fd, bool ReadWatch = true, bool WriteWatch = false, bool ExceptWatch = true); 00160 00161 00162 private: 00165 pthread_mutex_t accessMutex; 00167 pthread_mutex_t subscriptionMutex; 00168 protected: 00171 virtual void Lock(void); 00173 virtual void Unlock(void); 00174 00176 virtual void SubscriptionLock(void); 00178 virtual void SubscriptionUnlock(void); 00179 00183 virtual void TestCancel() {}; 00184 00185 00186 public: 00192 QueuePointer ret_queue; 00193 00208 virtual void Publish(player_devaddr_t addr, 00209 QueuePointer &queue, 00210 uint8_t type, 00211 uint8_t subtype, 00212 void* src=NULL, 00213 size_t deprecated=0, 00214 double* timestamp=NULL, 00215 bool copy=true); 00216 00230 virtual void Publish(player_devaddr_t addr, 00231 uint8_t type, 00232 uint8_t subtype, 00233 void* src=NULL, 00234 size_t deprecated=0, 00235 double* timestamp=NULL, 00236 bool copy=true); 00237 00238 00239 00248 virtual void Publish(QueuePointer &queue, 00249 player_msghdr_t* hdr, 00250 void* src, 00251 bool copy = true); 00252 00260 virtual void Publish(player_msghdr_t* hdr, 00261 void* src, 00262 bool copy = true); 00263 00264 00266 player_devaddr_t device_addr; 00267 00270 int entries; 00271 00279 bool alwayson; 00280 00282 QueuePointer InQueue; 00283 00291 Driver(ConfigFile *cf, 00292 int section, 00293 bool overwrite_cmds, 00294 size_t queue_maxlen, 00295 int interf); 00296 00304 Driver(ConfigFile *cf, 00305 int section, 00306 bool overwrite_cmds = true, 00307 size_t queue_maxlen = PLAYER_MSGQUEUE_DEFAULT_MAXLEN); 00308 00310 virtual ~Driver(); 00311 00314 int GetError() { return(this->error); } 00315 00325 virtual int Subscribe(player_devaddr_t addr); 00326 00340 virtual int Subscribe(QueuePointer &queue, player_devaddr_t addr) {return 1;}; 00341 00351 virtual int Unsubscribe(player_devaddr_t addr); 00352 00366 virtual int Unsubscribe(QueuePointer &queue, player_devaddr_t addr) {return 1;}; 00367 00374 virtual int Terminate(); 00375 00376 00383 virtual int Setup() {return 0;}; 00384 00390 virtual int Shutdown() {return 0;}; 00391 00399 void ProcessMessages(int maxmsgs); 00400 00405 void ProcessMessages(void); 00406 00416 virtual int ProcessMessage(QueuePointer &resp_queue, player_msghdr * hdr, 00417 void * data); 00418 00420 virtual void Update() 00421 { 00422 this->ProcessMessages(); 00423 } 00424 00432 virtual int ProcessInternalMessages(QueuePointer& resp_queue, 00433 player_msghdr * hdr, 00434 void * data); 00435 00443 virtual bool RegisterProperty(const char *key, Property *prop, ConfigFile* cf, int section); 00444 00452 virtual bool RegisterProperty(Property *prop, ConfigFile* cf, int section); 00453 }; 00454 00455 typedef enum player_thread_state 00456 { 00457 PLAYER_THREAD_STATE_STOPPED, 00458 PLAYER_THREAD_STATE_RUNNING, 00459 PLAYER_THREAD_STATE_STOPPING, 00460 PLAYER_THREAD_STATE_RESTARTING 00461 } player_thread_state_t; 00462 00463 class PLAYERCORE_EXPORT PlayerBarrier 00464 { 00465 public: 00466 PlayerBarrier() 00467 { 00468 pthread_mutex_init(&barrierMutex,NULL); 00469 pthread_cond_init(&barrierCond,NULL); 00470 barrierValue = 0; 00471 } 00472 ~PlayerBarrier() 00473 { 00474 pthread_mutex_destroy(&barrierMutex); 00475 pthread_cond_destroy(&barrierCond); 00476 }; 00477 00478 int SetValue(int Value) 00479 { 00480 return barrierValue = Value; 00481 }; 00482 00483 int Wait() 00484 { 00485 pthread_mutex_lock(&barrierMutex); 00486 assert(barrierValue); 00487 if (--barrierValue) 00488 pthread_cond_wait(&barrierCond,&barrierMutex); 00489 else 00490 pthread_cond_broadcast(&barrierCond); 00491 pthread_mutex_unlock(&barrierMutex); 00492 return 0; 00493 }; 00494 private: 00497 pthread_mutex_t barrierMutex; 00498 00499 int barrierValue; 00500 00501 pthread_cond_t barrierCond; 00502 00503 }; 00504 00505 00506 00544 class PLAYERCORE_EXPORT ThreadedDriver : public Driver 00545 { 00546 protected: 00547 00548 /* @brief Start the driver thread 00549 00550 This method is usually called from the overloaded Setup() method to 00551 create the driver thread. This will call Main(). */ 00552 virtual void StartThread(void); 00553 00558 virtual void StopThread(void); 00559 00562 static void* DummyMain(void *driver); 00563 00566 static void DummyMainQuit(void *driver); 00567 00568 private: 00572 pthread_t driverthread; 00573 00576 player_thread_state_t ThreadState; 00577 bool SetupSuccessful; 00578 00580 PlayerBarrier SetupBarrier; 00581 00582 protected: 00586 void TestCancel(); 00587 00588 00589 public: 00590 00597 ThreadedDriver(ConfigFile *cf, 00598 int section, 00599 bool overwrite_cmds, 00600 size_t queue_maxlen, 00601 int interf); 00602 00610 ThreadedDriver(ConfigFile *cf, 00611 int section, 00612 bool overwrite_cmds = true, 00613 size_t queue_maxlen = PLAYER_MSGQUEUE_DEFAULT_MAXLEN); 00614 00616 virtual ~ThreadedDriver(); 00617 00624 virtual int Setup(); 00625 00632 virtual int Shutdown(); 00633 00640 virtual int Terminate(); 00641 00647 virtual void Main(void) = 0; 00648 00650 virtual int MainSetup(void) {return 0;}; 00651 00656 virtual void MainQuit(void) {}; 00657 00667 bool Wait(double TimeOut=0.0); 00668 00669 virtual void Update() 00670 {}; 00671 00672 }; 00673 00674 00675 #endif