| 1 |
/* |
|---|
| 2 |
* Copyright (C) 2005-2008 by Daniel Wagner |
|---|
| 3 |
* Copyright (C) 2005-2008 by Pieter Palmers |
|---|
| 4 |
* |
|---|
| 5 |
* This file is part of FFADO |
|---|
| 6 |
* FFADO = Free Firewire (pro-)audio drivers for linux |
|---|
| 7 |
* |
|---|
| 8 |
* FFADO is based upon FreeBoB |
|---|
| 9 |
* |
|---|
| 10 |
* This program is free software: you can redistribute it and/or modify |
|---|
| 11 |
* it under the terms of the GNU General Public License as published by |
|---|
| 12 |
* the Free Software Foundation, either version 2 of the License, or |
|---|
| 13 |
* (at your option) version 3 of the License. |
|---|
| 14 |
* |
|---|
| 15 |
* This program is distributed in the hope that it will be useful, |
|---|
| 16 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 17 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 18 |
* GNU General Public License for more details. |
|---|
| 19 |
* |
|---|
| 20 |
* You should have received a copy of the GNU General Public License |
|---|
| 21 |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 22 |
* |
|---|
| 23 |
*/ |
|---|
| 24 |
|
|---|
| 25 |
#ifndef FFADODEVICE_H |
|---|
| 26 |
#define FFADODEVICE_H |
|---|
| 27 |
|
|---|
| 28 |
#include "libutil/OptionContainer.h" |
|---|
| 29 |
#include "libutil/PosixMutex.h" |
|---|
| 30 |
|
|---|
| 31 |
#include "libcontrol/BasicElements.h" |
|---|
| 32 |
|
|---|
| 33 |
#include "libieee1394/vendor_model_ids.h" |
|---|
| 34 |
|
|---|
| 35 |
#include <vector> |
|---|
| 36 |
#include <string> |
|---|
| 37 |
|
|---|
| 38 |
class DeviceManager; |
|---|
| 39 |
class ConfigRom; |
|---|
| 40 |
class Ieee1394Service; |
|---|
| 41 |
|
|---|
| 42 |
namespace Streaming { |
|---|
| 43 |
class StreamProcessor; |
|---|
| 44 |
} |
|---|
| 45 |
|
|---|
| 46 |
namespace Control { |
|---|
| 47 |
class Container; |
|---|
| 48 |
} |
|---|
| 49 |
|
|---|
| 50 |
/*! |
|---|
| 51 |
@brief Base class for device support |
|---|
| 52 |
|
|---|
| 53 |
This class should be subclassed to implement ffado support |
|---|
| 54 |
for a specific device. |
|---|
| 55 |
|
|---|
| 56 |
*/ |
|---|
| 57 |
class FFADODevice |
|---|
| 58 |
: public Util::OptionContainer, |
|---|
| 59 |
public Control::Container |
|---|
| 60 |
{ |
|---|
| 61 |
public: |
|---|
| 62 |
FFADODevice( DeviceManager&, std::auto_ptr< ConfigRom >( configRom ) ); |
|---|
| 63 |
|
|---|
| 64 |
virtual ~FFADODevice(); |
|---|
| 65 |
|
|---|
| 66 |
/** |
|---|
| 67 |
* @brief Compares the GUID of two FFADODevices |
|---|
| 68 |
* |
|---|
| 69 |
* This function compares the GUID of two FFADODevices and returns true |
|---|
| 70 |
* if the GUID of a is larger than the GUID of b . This is intended to be |
|---|
| 71 |
* used with the STL sort() algorithm. |
|---|
| 72 |
* |
|---|
| 73 |
* Note that GUID's are converted to integers for this. |
|---|
| 74 |
* |
|---|
| 75 |
* @param a pointer to first FFADODevice |
|---|
| 76 |
* @param b pointer to second FFADODevice |
|---|
| 77 |
* |
|---|
| 78 |
* @returns true if the GUID of a is larger than the GUID of b . |
|---|
| 79 |
*/ |
|---|
| 80 |
static bool compareGUID( FFADODevice *a, FFADODevice *b ); |
|---|
| 81 |
|
|---|
| 82 |
/// Returns the 1394 service of the FFADO device |
|---|
| 83 |
virtual Ieee1394Service& get1394Service(); |
|---|
| 84 |
/// Returns the ConfigRom object of the device node. |
|---|
| 85 |
virtual ConfigRom& getConfigRom() const; |
|---|
| 86 |
|
|---|
| 87 |
/** |
|---|
| 88 |
* @brief Called by DeviceManager to load device model from cache. |
|---|
| 89 |
* |
|---|
| 90 |
* This function is called before discover in order to speed up |
|---|
| 91 |
* system initializing. |
|---|
| 92 |
* |
|---|
| 93 |
* @returns true if device was cached and successfully loaded from cache |
|---|
| 94 |
*/ |
|---|
| 95 |
virtual bool loadFromCache(); |
|---|
| 96 |
|
|---|
| 97 |
/** |
|---|
| 98 |
* @brief Called by DeviceManager to allow device driver to save a cache version |
|---|
| 99 |
* of the current configuration. |
|---|
| 100 |
* |
|---|
| 101 |
* @returns true if caching was successful. False doesn't mean an error just, |
|---|
| 102 |
* the driver was unable to store the configuration |
|---|
| 103 |
*/ |
|---|
| 104 |
virtual bool saveCache(); |
|---|
| 105 |
|
|---|
| 106 |
/** |
|---|
| 107 |
* @brief Called by DeviceManager to check whether a device requires rediscovery |
|---|
| 108 |
* |
|---|
| 109 |
* This function is called to figure out if the device has to be rediscovered |
|---|
| 110 |
* e.g. after a bus reset where the device internal structure changed. |
|---|
| 111 |
* |
|---|
| 112 |
* @returns true if device requires rediscovery |
|---|
| 113 |
*/ |
|---|
| 114 |
virtual bool needsRediscovery(); |
|---|
| 115 |
|
|---|
| 116 |
/** |
|---|
| 117 |
* @brief This is called by the DeviceManager to create an instance of the device |
|---|
| 118 |
* |
|---|
| 119 |
* This function enables the FFADODevice to return a subclass of itself should that |
|---|
| 120 |
* be needed. If we don't do this we'd need to know about the subclasses in the |
|---|
| 121 |
* devicemanager, whilst now we don't. |
|---|
| 122 |
* |
|---|
| 123 |
* The function should return an instance of either the class itself or a subclass |
|---|
| 124 |
* of itself. |
|---|
| 125 |
* |
|---|
| 126 |
* This should be overridden in any subclass. |
|---|
| 127 |
* |
|---|
| 128 |
* @return a new instance of the AvDevice type, NULL when unsuccessful |
|---|
| 129 |
*/ |
|---|
| 130 |
static FFADODevice * createDevice( std::auto_ptr<ConfigRom>( x )); |
|---|
| 131 |
|
|---|
| 132 |
/** |
|---|
| 133 |
* @brief This is called by the DeviceManager to discover & configure the device |
|---|
| 134 |
* |
|---|
| 135 |
* @return true if the device was discovered successfuly |
|---|
| 136 |
*/ |
|---|
| 137 |
virtual bool discover() = 0; |
|---|
| 138 |
|
|---|
| 139 |
/** |
|---|
| 140 |
* @brief Set the samping frequency |
|---|
| 141 |
* @param samplingFrequency |
|---|
| 142 |
* @return true if successful |
|---|
| 143 |
*/ |
|---|
| 144 |
virtual bool setSamplingFrequency( int samplingFrequency ) = 0; |
|---|
| 145 |
/** |
|---|
| 146 |
* @brief get the samplingfrequency as an integer |
|---|
| 147 |
* @return the sampling frequency as integer |
|---|
| 148 |
*/ |
|---|
| 149 |
virtual int getSamplingFrequency( ) = 0; |
|---|
| 150 |
|
|---|
| 151 |
/** |
|---|
| 152 |
* @brief get the supported sampling frequencies |
|---|
| 153 |
* @return a vector containing the supported sampling frequencies |
|---|
| 154 |
*/ |
|---|
| 155 |
virtual std::vector<int> getSupportedSamplingFrequencies( ) = 0; |
|---|
| 156 |
|
|---|
| 157 |
/** |
|---|
| 158 |
* @brief sync state enum |
|---|
| 159 |
*/ |
|---|
| 160 |
enum eSyncState { |
|---|
| 161 |
eSS_Unknown=0, |
|---|
| 162 |
eSS_Locked=1, |
|---|
| 163 |
eSS_Unlocked=2, |
|---|
| 164 |
}; |
|---|
| 165 |
|
|---|
| 166 |
/** |
|---|
| 167 |
* @brief gets the devices current synchronization state |
|---|
| 168 |
* @return the device's sync state |
|---|
| 169 |
*/ |
|---|
| 170 |
virtual enum eSyncState getSyncState( ); |
|---|
| 171 |
|
|---|
| 172 |
/** |
|---|
| 173 |
* @brief clock source types |
|---|
| 174 |
*/ |
|---|
| 175 |
enum eClockSourceType { |
|---|
| 176 |
eCT_Invalid, ///> invalid entry (e.g. on error) |
|---|
| 177 |
eCT_Auto, ///> automatically select clock source |
|---|
| 178 |
eCT_Internal, ///> internal sync (unspecified) |
|---|
| 179 |
eCT_1394Bus, ///> Sync on the 1394 bus clock (e.g. CSP) |
|---|
| 180 |
eCT_SytMatch, ///> SYT match on incoming audio stream |
|---|
| 181 |
eCT_SytStream, ///> SYT match on incoming sync stream |
|---|
| 182 |
eCT_WordClock, ///> SYT on WordClock input |
|---|
| 183 |
eCT_SPDIF, ///> SYT on SPDIF input |
|---|
| 184 |
eCT_ADAT, ///> SYT on ADAT input |
|---|
| 185 |
eCT_TDIF, ///> SYT on TDIF input |
|---|
| 186 |
eCT_AES, ///> SYT on AES input |
|---|
| 187 |
eCT_SMPTE, ///> SMPTE clock |
|---|
| 188 |
}; |
|---|
| 189 |
|
|---|
| 190 |
/** |
|---|
| 191 |
* @brief convert the clock source type to a C string |
|---|
| 192 |
* @return a C string describing the clock source type |
|---|
| 193 |
*/ |
|---|
| 194 |
static const char *ClockSourceTypeToString(enum eClockSourceType); |
|---|
| 195 |
|
|---|
| 196 |
/** |
|---|
| 197 |
* @brief Clock source identification struct |
|---|
| 198 |
*/ |
|---|
| 199 |
class ClockSource { |
|---|
| 200 |
public: |
|---|
| 201 |
ClockSource() |
|---|
| 202 |
: type( eCT_Invalid ) |
|---|
| 203 |
, id( 0 ) |
|---|
| 204 |
, valid( false ) |
|---|
| 205 |
, active( false ) |
|---|
| 206 |
, locked( true ) |
|---|
| 207 |
, slipping( false ) |
|---|
| 208 |
, description( "" ) |
|---|
| 209 |
{}; |
|---|
| 210 |
/// indicates the type of the clock source (e.g. eCT_ADAT) |
|---|
| 211 |
enum eClockSourceType type; |
|---|
| 212 |
/// indicated the id of the clock source (e.g. id=1 => clocksource is ADAT_1) |
|---|
| 213 |
unsigned int id; |
|---|
| 214 |
/// is the clock source valid (i.e. can be selected) at this moment? |
|---|
| 215 |
bool valid; |
|---|
| 216 |
/// is the clock source active at this moment? |
|---|
| 217 |
bool active; |
|---|
| 218 |
/// is the clock source locked? |
|---|
| 219 |
bool locked; |
|---|
| 220 |
/// is the clock source slipping? |
|---|
| 221 |
bool slipping; |
|---|
| 222 |
/// description of the clock struct (optional) |
|---|
| 223 |
std::string description; |
|---|
| 224 |
|
|---|
| 225 |
bool operator==(const ClockSource& x) { |
|---|
| 226 |
return (type == x.type) && (id == x.id); |
|---|
| 227 |
} |
|---|
| 228 |
}; |
|---|
| 229 |
|
|---|
| 230 |
typedef std::vector< ClockSource > ClockSourceVector; |
|---|
| 231 |
typedef std::vector< ClockSource >::iterator ClockSourceVectorIterator; |
|---|
| 232 |
|
|---|
| 233 |
/** |
|---|
| 234 |
* @brief Get the clocksources supported by this device |
|---|
| 235 |
* |
|---|
| 236 |
* This function returns a vector of ClockSource structures that contains |
|---|
| 237 |
* one entry for every clock source supported by the device. |
|---|
| 238 |
* |
|---|
| 239 |
* @returns a vector of ClockSource structures |
|---|
| 240 |
*/ |
|---|
| 241 |
virtual ClockSourceVector getSupportedClockSources() = 0; |
|---|
| 242 |
|
|---|
| 243 |
|
|---|
| 244 |
/** |
|---|
| 245 |
* @brief Sets the active clock source of this device |
|---|
| 246 |
* |
|---|
| 247 |
* This function sets the clock source of the device. |
|---|
| 248 |
* |
|---|
| 249 |
* @returns true upon success. false upon failure. |
|---|
| 250 |
*/ |
|---|
| 251 |
virtual bool setActiveClockSource(ClockSource) = 0; |
|---|
| 252 |
|
|---|
| 253 |
/** |
|---|
| 254 |
* @brief Returns the active clock source of this device |
|---|
| 255 |
* |
|---|
| 256 |
* This function returns the active clock source of the device. |
|---|
| 257 |
* |
|---|
| 258 |
* @returns the active ClockSource |
|---|
| 259 |
*/ |
|---|
| 260 |
virtual ClockSource getActiveClockSource() = 0; |
|---|
| 261 |
|
|---|
| 262 |
/** |
|---|
| 263 |
* @brief stream states |
|---|
| 264 |
*/ |
|---|
| 265 |
enum eStreamingState { |
|---|
| 266 |
eSS_Idle = 0, ///> not streaming |
|---|
| 267 |
eSS_Sending = 1, ///> the device is sending a stream |
|---|
| 268 |
eSS_Receiving = 2, ///> the device is receiving a stream |
|---|
| 269 |
eSS_Both = 3, ///> the device is sending and receiving a stream |
|---|
| 270 |
}; |
|---|
| 271 |
|
|---|
| 272 |
/** |
|---|
| 273 |
* @brief gets the devices current synchronization state |
|---|
| 274 |
* @return the device's sync state |
|---|
| 275 |
*/ |
|---|
| 276 |
virtual enum eStreamingState getStreamingState(); |
|---|
| 277 |
|
|---|
| 278 |
/** |
|---|
| 279 |
* @brief Outputs the device configuration to stderr/stdout [debug helper] |
|---|
| 280 |
* |
|---|
| 281 |
* This function prints out a (detailed) description of the |
|---|
| 282 |
* device detected, and its configuration. |
|---|
| 283 |
*/ |
|---|
| 284 |
virtual void showDevice(); |
|---|
| 285 |
|
|---|
| 286 |
/** |
|---|
| 287 |
* @brief Lock the device |
|---|
| 288 |
* |
|---|
| 289 |
* This is called by the streaming layer before we start manipulating |
|---|
| 290 |
* and/or using the device. |
|---|
| 291 |
* |
|---|
| 292 |
* It should implement the mechanisms provided by the device to |
|---|
| 293 |
* make sure that no other controller claims control of the device. |
|---|
| 294 |
* |
|---|
| 295 |
* @return true if successful, false if not |
|---|
| 296 |
*/ |
|---|
| 297 |
virtual bool lock() = 0; |
|---|
| 298 |
|
|---|
| 299 |
/** |
|---|
| 300 |
* @brief Unlock the device |
|---|
| 301 |
* |
|---|
| 302 |
* This is called by the streaming layer after we finish manipulating |
|---|
| 303 |
* and/or using the device. |
|---|
| 304 |
* |
|---|
| 305 |
* It should implement the mechanisms provided by the device to |
|---|
| 306 |
* give up exclusive control of the device. |
|---|
| 307 |
* |
|---|
| 308 |
* @return true if successful, false if not |
|---|
| 309 |
*/ |
|---|
| 310 |
virtual bool unlock() = 0; |
|---|
| 311 |
|
|---|
| 312 |
/** |
|---|
| 313 |
* @brief Enable streaming on all 'started' streams |
|---|
| 314 |
* |
|---|
| 315 |
* Enables the ISO streaming on all streams that are 'started' |
|---|
| 316 |
* using startStreamByIndex. This is useful to control a 'master enable' |
|---|
| 317 |
* function on the device. |
|---|
| 318 |
* |
|---|
| 319 |
* @return true if successful |
|---|
| 320 |
*/ |
|---|
| 321 |
virtual bool enableStreaming(); |
|---|
| 322 |
|
|---|
| 323 |
/** |
|---|
| 324 |
* @brief Disable streaming on all streams |
|---|
| 325 |
* |
|---|
| 326 |
* Disables ISO streaming on all streams. |
|---|
| 327 |
* This is useful to control a 'master enable' |
|---|
| 328 |
* function on the device. |
|---|
| 329 |
* |
|---|
| 330 |
* @return true if successful |
|---|
| 331 |
*/ |
|---|
| 332 |
virtual bool disableStreaming(); |
|---|
| 333 |
|
|---|
| 334 |
/** |
|---|
| 335 |
* @brief Prepare the device |
|---|
| 336 |
* |
|---|
| 337 |
* This is called by the streaming layer after the configuration |
|---|
| 338 |
* parameters (e.g. sample rate) are set, and before |
|---|
| 339 |
* getStreamProcessor[*] functions are called. |
|---|
| 340 |
* |
|---|
| 341 |
* It should be used to prepare the device's streamprocessors |
|---|
| 342 |
* based upon the device's current configuration. Normally |
|---|
| 343 |
* the streaming layer will not change the device's configuration |
|---|
| 344 |
* after calling this function. |
|---|
| 345 |
* |
|---|
| 346 |
* @return true if successful, false if not |
|---|
| 347 |
*/ |
|---|
| 348 |
virtual bool prepare() = 0; |
|---|
| 349 |
|
|---|
| 350 |
/** |
|---|
| 351 |
* @brief Performs operations needed to prepare for a stream start |
|---|
| 352 |
* |
|---|
| 353 |
* This is called by the streaming layer just before streaming is |
|---|
| 354 |
* started. It provides a place where reset activity can be done which |
|---|
| 355 |
* ensures the object is ready to restart streaming even if streaming |
|---|
| 356 |
* has been previously started and stopped. |
|---|
| 357 |
* |
|---|
| 358 |
* @return true if successful, false if not |
|---|
| 359 |
*/ |
|---|
| 360 |
virtual bool resetForStreaming() { return true; } |
|---|
| 361 |
|
|---|
| 362 |
/** |
|---|
| 363 |
* @brief Returns the number of ISO streams implemented/used by this device |
|---|
| 364 |
* |
|---|
| 365 |
* Most likely this is 2 streams, i.e. one transmit stream and one |
|---|
| 366 |
* receive stream. However there are devices that implement more, for |
|---|
| 367 |
* example BeBoB's implement 4 streams: |
|---|
| 368 |
* - 2 audio streams (1 xmit/1 recv) |
|---|
| 369 |
* - 2 sync streams (1 xmit/1 recv), which are an optional sync source |
|---|
| 370 |
* for the device. |
|---|
| 371 |
* |
|---|
| 372 |
* @note you have to have a StreamProcessor for every stream. I.e. |
|---|
| 373 |
* getStreamProcessorByIndex(i) should return a valid StreamProcessor |
|---|
| 374 |
* for i=0 to i=getStreamCount()-1 |
|---|
| 375 |
* |
|---|
| 376 |
* @return number of streams available (both transmit and receive) |
|---|
| 377 |
*/ |
|---|
| 378 |
virtual int getStreamCount() = 0; |
|---|
| 379 |
|
|---|
| 380 |
/** |
|---|
| 381 |
* @brief Returns the StreamProcessor object for the stream with index i |
|---|
| 382 |
* |
|---|
| 383 |
* @note a streamprocessor returned by getStreamProcessorByIndex(i) |
|---|
| 384 |
* cannot be the same object as one returned by |
|---|
| 385 |
* getStreamProcessorByIndex(j) if i isn't equal to j |
|---|
| 386 |
* @note you cannot have two streamprocessors handling the same ISO |
|---|
| 387 |
* channel (on the same port) |
|---|
| 388 |
* |
|---|
| 389 |
* @param i : Stream index (i has to be smaller than getStreamCount()) |
|---|
| 390 |
* @return a StreamProcessor object if successful, NULL otherwise |
|---|
| 391 |
*/ |
|---|
| 392 |
virtual Streaming::StreamProcessor *getStreamProcessorByIndex(int i) = 0; |
|---|
| 393 |
|
|---|
| 394 |
/** |
|---|
| 395 |
* @brief starts the stream with index i |
|---|
| 396 |
* |
|---|
| 397 |
* This function is called by the streaming layer when this stream should |
|---|
| 398 |
* be started, i.e. the device should start sending data or should be prepared to |
|---|
| 399 |
* be ready to receive data. |
|---|
| 400 |
* |
|---|
| 401 |
* It returns the channel number that was assigned for this stream. |
|---|
| 402 |
* Channel allocation should be done using the allocation functions provided by the |
|---|
| 403 |
* Ieee1394Service object that is passed in the constructor. |
|---|
| 404 |
* |
|---|
| 405 |
* @param i : Stream index (i has to be smaller than getStreamCount()) |
|---|
| 406 |
* @return true if successful, false if not |
|---|
| 407 |
*/ |
|---|
| 408 |
virtual bool startStreamByIndex(int i) = 0; |
|---|
| 409 |
|
|---|
| 410 |
/** |
|---|
| 411 |
* @brief stops the stream with index i |
|---|
| 412 |
* |
|---|
| 413 |
* @param i : Stream index (i has to be smaller than getStreamCount()) |
|---|
| 414 |
* @return true if successful, false if not |
|---|
| 415 |
*/ |
|---|
| 416 |
virtual bool stopStreamByIndex(int i) = 0; |
|---|
| 417 |
|
|---|
| 418 |
/** |
|---|
| 419 |
* set verbosity level |
|---|
| 420 |
*/ |
|---|
| 421 |
virtual void setVerboseLevel(int l); |
|---|
| 422 |
|
|---|
| 423 |
/** |
|---|
| 424 |
* @brief return the node id of this device |
|---|
| 425 |
* |
|---|
| 426 |
* @return the node id |
|---|
| 427 |
*/ |
|---|
| 428 |
int getNodeId(); |
|---|
| 429 |
|
|---|
| 430 |
/** |
|---|
| 431 |
* @brief return the nick name of this device |
|---|
| 432 |
* |
|---|
| 433 |
* @return string containing the name |
|---|
| 434 |
*/ |
|---|
| 435 |
virtual std::string getNickname(); |
|---|
| 436 |
|
|---|
| 437 |
/** |
|---|
| 438 |
* @brief set the nick name of this device |
|---|
| 439 |
* @param name new nickname |
|---|
| 440 |
* @return true if successful |
|---|
| 441 |
*/ |
|---|
| 442 |
virtual bool setNickname(std::string name); |
|---|
| 443 |
|
|---|
| 444 |
/** |
|---|
| 445 |
* @brief return whether the nick name of this device can be changed |
|---|
| 446 |
* |
|---|
| 447 |
* @return true if the nick can be changed |
|---|
| 448 |
*/ |
|---|
| 449 |
virtual bool canChangeNickname(); |
|---|
| 450 |
|
|---|
| 451 |
/** |
|---|
| 452 |
* @brief handle a bus reset |
|---|
| 453 |
* |
|---|
| 454 |
* Called whenever a bus reset is detected. Handle everything |
|---|
| 455 |
* that has to be done to cope with a bus reset. |
|---|
| 456 |
* |
|---|
| 457 |
*/ |
|---|
| 458 |
// FIXME: not virtual? |
|---|
| 459 |
void handleBusReset(); |
|---|
| 460 |
|
|---|
| 461 |
// the Control::Container functions |
|---|
| 462 |
virtual std::string getName(); |
|---|
| 463 |
virtual bool setName( std::string n ) |
|---|
| 464 |
{ return false; }; |
|---|
| 465 |
|
|---|
| 466 |
DeviceManager& getDeviceManager() |
|---|
| 467 |
{return m_pDeviceManager;}; |
|---|
| 468 |
private: |
|---|
| 469 |
std::auto_ptr<ConfigRom>( m_pConfigRom ); |
|---|
| 470 |
DeviceManager& m_pDeviceManager; |
|---|
| 471 |
Control::Container* m_genericContainer; |
|---|
| 472 |
protected: |
|---|
| 473 |
DECLARE_DEBUG_MODULE; |
|---|
| 474 |
Util::PosixMutex m_DeviceMutex; |
|---|
| 475 |
}; |
|---|
| 476 |
|
|---|
| 477 |
#endif |
|---|