Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

CascadeUPnP.h

Go to the documentation of this file.
00001 //
00002 // CascadeUPnP.h - interface file for class CascadeUPnP
00003 //
00004 // Copyright (c) 2004, Roku, LLC.  All rights reserved.
00005 //
00007 
00008 #ifndef _ROKU_INCLUDE_CASCADE_NET_CASCADEUPNP_H
00009 #define _ROKU_INCLUDE_CASCADE_NET_CASCADEUPNP_H
00010 
00011 #include <cascade/util/CascadeNewArray.h>
00012 #include <cascade/util/CascadeString.h>
00013 #include <cascade/interthread/CascadeMutex.h>
00014 
00016 // TODO:  (notes on original VDK API)
00017 //
00018 // Not currently exposed in this UPnP interface is control and subscription
00019 // of events via the services exposed by a UPnP device.  This is currently
00020 // a discovery-only API.
00021 //
00022 // FIXME: declarations currently reside in sbAllegro.cpp
00023 
00025 // enable new cascade UPnP interface except on VDK and WIN32
00026 #define _NEW_CASCADE_UPNP_IFACE
00027 #ifdef WIN32
00028 #undef _NEW_CASCADE_UPNP_IFACE
00029 #endif
00030 #ifdef AD_VDK_OS
00031 #undef _NEW_CASCADE_UPNP_IFACE
00032 #endif
00033 
00035 // class CascadeUPnP
00036 #ifndef _NEW_CASCADE_UPNP_IFACE
00037 #define CascadeAppMessageSink CascadeObject
00038 #else
00039 #include <cascade/app/CascadeAppMessageSink.h>
00040 #endif
00041 
00042 class CascadeUPnP : public CascadeAppMessageSink
00043 {
00044 private:
00045     class UPnP; friend class UPnP;
00046 public:
00047     CascadeUPnP();
00048     virtual ~CascadeUPnP();
00049     
00050 public:
00051     // class Device is used to report discovered UPnP devices on the network
00052     enum DeviceStatus   { kOnline = 0, kOffline = 1 }; // could add kExpired
00053     class Device
00054     {
00055     public:
00056         CascadeString   m_deviceUUID;
00057             // Universally Unique Identifier for this device
00058             // NOTE: does NOT begin with "uuid:"
00059         CascadeString   m_deviceType;
00060             // UPnP device type, e.g., "schemas-upnp-org:device:MediaServer:1"
00061             // NOTE: does NOT begin with "urn:"
00062         DeviceStatus    m_deviceStatus;
00063             // Is this device online?
00064         CascadeString   m_deviceDescriptionURL;
00065             // URL to the device's XML description document
00066         bool            m_bRootDevice;
00067             // is this device a root device?
00068         
00069         CascadeNewArray<CascadeString>  m_serviceTypes;
00070             // array of strings that describe services a la Service::m_serviceType
00071     public:
00072 #ifdef _NEW_CASCADE_UPNP_IFACE
00073         bool operator == (const Device & that) const;
00074             // compares this with that returning true if they are equivalent,
00075             // false otherwise.  Equivalency means the following:
00076             // m_deviceUUID == that.m_deviceUUID; same for m_deviceType, status,
00077             // description url and device type.
00078             //
00079             // m_servicesTypes is scanned and compared with that.m_serviceTypes
00080             // to determine if they both contain the same number and type of
00081             // services, though not necessarily in the same order in the
00082             // m_serviceTypes array
00083         Device & operator = (const Device & that);
00084         inline bool IsMediaServer() const { return (m_deviceType == CascadeUPnP::MediaServerDeviceType()); }
00085 #endif
00086     };
00087     // class Service describes a service available on a device, a list of which
00088     // is provided in class DeviceDescription, below
00089     class Service
00090     {
00091     public:
00092         CascadeString   m_serviceType;
00093             // a service type string of the form:
00094             // "urn:<domain-name>:service:<service-type>:<v>"
00095             // where <domain-name> is "schemas-upnp-org" for registered services
00096             // and <service-type> is the service and <v> is an integer version number
00097         CascadeString   m_serviceId;
00098             // a unique identifier to id this service when communicating with the server
00099         CascadeString   m_scpdUrl;
00100             // url for retrieving the service description
00101             // (Service Control Protocol Definition URL)
00102         CascadeString   m_controlUrl;
00103             // url for invoking actions
00104         CascadeString   m_eventSubUrl;
00105             // url for subscribing to events
00106     };
00107     // class DeviceIcon describes an icon available on a device, a list of which
00108     // is provided in class DeviceDescription, below
00109     class DeviceIcon
00110     {
00111     public:
00112         CascadeString   m_mimeType;
00113         CascadeString   m_url;
00114         u16             m_nWidth;
00115         u16             m_nHeight;
00116         u16             m_nDepth;
00117     };
00118     // class DeviceDescription provides an in-depth description of a UPnP device.
00119     // Returned by GetDeviceDescription(), below.
00120     class DeviceDescription
00121     {
00122     public:
00123         CascadeString   m_deviceType;
00124             // UPnP device type.  For std devices defined by a UPnP Forum working committee,
00125             // must start with "urn:schemas-upnp-org:device:", followed by a device type
00126             // suffix, colon, and an integer device version.  (Required)
00127         CascadeString   m_friendlyName;
00128             // Short description for end user.  Should be localized.  (Required)
00129         CascadeString   m_manufacturer;
00130             // Manufacturer.  May be localized.  (Required)
00131         CascadeString   m_manufacturerURL;
00132             // Web site for manufacturer.  May be localized.  (Optional)
00133         CascadeString   m_modelDescription;
00134             // Long description for user.  Should be localized.  (Recommended)
00135         CascadeString   m_modelName;
00136             // Model name.  May be localized.  (Required)
00137         CascadeString   m_modelNumber;
00138             // Model Number.  May be localized.  (Recommended)
00139         CascadeString   m_modelURL;
00140             // Web site for model.  May be localized.  (Optional)
00141         CascadeString   m_serialNumber;
00142             // Serial number.  May be localized.  (Recommended)
00143         CascadeString   m_udn;
00144             // Unique Device Name, begins with "uuid:", is a Universally-Unique ID.  (Required)
00145         #ifdef _NEW_CASCADE_UPNP_IFACE
00146             CascadeString   m_deviceUUID;
00147         #endif
00148         CascadeString   m_upc;
00149             // Universal Product Code.  12-digit, all-numeric product code.  (Optional)
00150 
00151         CascadeNewArray<Service>        m_deviceServices;
00152             // list of services available on the device
00153         CascadeNewArray<DeviceIcon>     m_deviceIcons;
00154             // list of icons with which to represent the device
00155     };
00156     class AVObject
00157     {
00158     public:
00159         AVObject() : m_classActions(0), m_numericProperties(0), m_stringProperties(0), m_personas(0), m_resources(0) { }
00160     public:
00161         enum ObjectType
00162         {
00163             kContainer = 0,
00164             kItem
00165         };
00166         enum ClassActionType
00167         {
00168             kCreate = 0,
00169             kSearch
00170         };
00171         enum NumericPropertyType
00172         {
00173             kStorageTotal = 0,
00174             kStorageUsed,
00175             kStorageFree,
00176             kStorageMaxPartition,
00177             kDVDRegionCode,
00178             kOriginalTrackNumber
00179         };
00180         enum StringPropertyType
00181         {
00182             kWriteStatus = 0,
00183             kStorageMedium,
00184             kData,
00185             kActor,
00186             kAlbum,
00187             kArtist,
00188             kAuthor,
00189             kCreator,
00190             kGenre,
00191             kDirector,
00192             kProducer,
00193             kPublisher,
00194             kAlbumArtURL,
00195             kArtistDiscographyURI,
00196             kLyricsURI,
00197             kRelation,
00198             kPlaylist,
00199             kIconURI,
00200             kRegion,
00201             kRating,
00202             kRights,
00203             kLanguage,
00204             kRadioCallSign,
00205             kRadioStationID,
00206             kRadioBand,
00207             kChannelNumber,
00208             kChannelName,
00209             kScheduledStartTime,
00210             kScheduledEndTime,
00211             kDescription,
00212             kTOC,
00213             kUserAnnotation
00214         };
00215         enum PersonaType
00216         {
00217             kActorPersona = 0,
00218             kArtistPersona,
00219             kAuthorPersona
00220         };
00221         class ClassAction
00222         {
00223         public:
00224             ClassActionType     m_type;
00225             CascadeString       m_class;
00226             CascadeString       m_className;
00227             bool                m_bIncludeDerived;
00228         };
00229         class NumericProperty
00230         {
00231         public:
00232             NumericPropertyType m_type;
00233             s32                 m_nValue;
00234         };
00235         class StringProperty
00236         {
00237         public:
00238             StringPropertyType  m_type;
00239             CascadeString       m_value;
00240         };
00241         class Persona
00242         {
00243         public:
00244             PersonaType         m_type;
00245             CascadeString       m_name;
00246             CascadeString       m_role;
00247         };
00248         class Resource
00249         {
00250         public:
00251             CascadeString       m_protocolInfo;
00252             CascadeString       m_protection;
00253             CascadeString       m_URI;
00254             CascadeString       m_importURI;
00255             u32                 m_nSize;
00256             CascadeString       m_duration;
00257             u32                 m_nBitrate;
00258             u32                 m_nSampleRate;
00259             u32                 m_nBitsPerSample;
00260             u32                 m_nNumChannels;
00261             CascadeString       m_resolution;
00262             u32                 m_nColorDepth;
00263         };
00264     public:
00265         ObjectType                          m_type;
00266         CascadeString                       m_id;
00267         CascadeString                       m_idParent;
00268         CascadeString                       m_idRef;
00269         bool                                m_bRestricted;
00270         u32                                 m_nChildCount;
00271         bool                                m_bSearchable;
00272         CascadeString                       m_title;
00273         CascadeString                       m_class;
00274         CascadeString                       m_className;
00275         CascadeNewArray<ClassAction>        m_classActions;
00276         CascadeNewArray<NumericProperty>    m_numericProperties;
00277         CascadeNewArray<StringProperty>     m_stringProperties;
00278         CascadeNewArray<Persona>            m_personas;
00279         CascadeNewArray<Resource>           m_resources;
00280     };
00281     class AVObjectArray : private CascadeNewArray<AVObject *>
00282     {
00283     public:
00284         AVObjectArray() : CascadeNewArray<AVObject *>(0), m_nOwningTransactionID(0) { }
00285         virtual ~AVObjectArray();
00286     public:
00287         void Empty();
00288             // frees all elements of the array and sets the size to zero
00289         AVObject * TakeOwnership(u32 nIndex);
00290             // TakeOwnership() returns the AVObject * at index nIndex
00291             // and takes ownership of the AVObject *.  After calling
00292             // TakeOwnership() it is your responsibility to free the
00293             // returned AVObject *.
00294         u32 GetSize();
00295         AVObject * operator[](u32 nIndex) const;
00296         AVObject * GetAt(u32 nIndex) const;
00297         u32 GetOwningTransactionID() const;
00298 
00299     private:
00300         u32 m_nOwningTransactionID;
00301         CascadeMutex m_mutex;
00302         friend class UPnP;
00303         friend class CascadeUPnPMessage;
00304     };
00305 public:
00306     #ifdef _NEW_CASCADE_UPNP_IFACE
00307     // We now have two versions - first the new Cascade version in which
00308     // all requests return cancelable transaction ids ,
00309     // and the existing SoundBridge version which is retained for compatibility.
00310     // The Cascade version is implemented in CascadeUPnP.cpp; the SB version
00311     // is in sbAllegro.cpp.
00312     // FIRST THE NEW DULCHUTES-VERSION!
00313         enum TransactionResult
00314         {
00315             kUnknownDevice = 0,
00316             kDeviceNotUPnPAVServer,
00317             kDeviceNotWMCServer,
00318             kDeviceOffline,
00319             kDeviceError,
00320             kTimeout,
00321             kResourceBusy,
00322             kDeviceDescriptionNotCached,
00323             kRemoteSystemElementNotResponding,
00324             kAllocationError,
00325             kDataError,
00326             kParameterError,
00327             kEnumerationAborted,
00328             kObjectArrayInUse,
00329             kReissueTransaction,
00330             kSuccess
00331         };
00332 
00333         // asynchronous transactions - not requiring a cached device description
00334         virtual u32  CatalogLocalDevices();
00335         virtual u32  RequestDeviceDescription(const CascadeString & deviceUUID);
00336         virtual u32  RequestDeviceMount(const CascadeString & deviceUUID);
00337 
00338         // asynchronous transactions - requiring a cached device description
00339         virtual u32  RequestWMCAuthorizationStatus(const CascadeString & deviceUUID);
00340         virtual u32  RequestAVSearchCapabilities(const CascadeString & deviceUUID);
00341         
00342         virtual u32  InitiateAVSearch(
00343                         const CascadeString & deviceUUID,
00344                         const CascadeString & containerObjectID,
00345                         const CascadeString & searchTerm,
00346                         const CascadeString & filterTerm,
00347                         const CascadeString & sortTerm,
00348                                         u32   nStartIndex,
00349                                         u32   nCount,
00350                               AVObjectArray & arrayToFill);
00351         
00352         virtual u32  InitiateAVBrowse(
00353                         const CascadeString & deviceUUID,
00354                         const CascadeString & containerObjectID,
00355                         const CascadeString & filterTerm,
00356                         const CascadeString & sortTerm,
00357                                         u32   nStartIndex,
00358                                         u32   nCount,
00359                               AVObjectArray & arrayToFill);
00360         
00361         virtual u32  InitiateAVObjectFetch(
00362                         const CascadeString & deviceUUID,
00363                         const CascadeString & objectID,
00364                         const CascadeString & filterTerm,
00365                                    AVObject & objectToSet);
00366 
00367         // cancelling asynchronous transactions
00368         virtual void CancelTransaction(u32 nTransactionID);
00369 
00370         // asynchronous transaction result notification
00371         virtual void OnCatalogResult(const Device & device);
00372         virtual void OnDeviceDescriptionResult(u32 nTransactionID, TransactionResult result, const DeviceDescription & deviceDescription);
00373         virtual void OnDeviceMountResult(u32 nTransactionID, TransactionResult result, bool bMounted);
00374         virtual void OnWMCAuthorizationStatusResult(u32 nTransactionID, TransactionResult result, bool bAuthorized);
00375         virtual void OnAVSearchCapabilitiesResult(u32 nTransactionID, TransactionResult result, const CascadeString & searchCapabilities);
00376         virtual void OnAVSearchResult(u32 nTransactionID, TransactionResult result, u32 nMatchCount, AVObjectArray & objectArray, bool bComplete);
00377             // OnAVSearchResult will get repeatedly called back, growing
00378             // objectArray until (a) your desired count is reached, (b)
00379             // objectArray contains nMatchCount items, or (c) an error occurs.
00380             // In any of these cases, bComplete will be set to true, indicating
00381             // that this is the last callback and that objectArray will no longer
00382             // be touched by CascadeUPnP - you are free to delete it.
00383 
00384         virtual void OnAVBrowseResult(u32 nTransactionID, TransactionResult result, u32 nMatchCount, AVObjectArray & objectArray, bool bComplete);
00385         virtual void OnAVObjectFetchResult(u32 nTransactionID, TransactionResult result, AVObject & object);
00386                 
00387         // synchronous requests        
00388         virtual bool GetDeviceFromUUID(const CascadeString & deviceUUID, Device & deviceToSet);
00389             // GetDeviceFromUUID() will fill deviceToSet with the device structure for the device identified
00390             // by deviceUUID, if it is cached returning true if so, false if it is not cached.
00391             // This is a synchronous function provided for convenience.  The preferred method of getting
00392             // devices is to call CatalogLocalDevices().  This function may
00393             // be used on mounted devices - once a device is mounted its device is cached.
00394 
00395         virtual bool GetCachedDeviceDescription(const CascadeString & deviceUUID, DeviceDescription & deviceDescriptionToSet);
00396             // GetCachedDeviceDescription() will fill deviceDescriptionToSet with the deviceDescription for the device identified
00397             // by deviceUUID, if it is cached returning true if so, false if it is not cached.
00398             // This is a synchronous function provided for convenience.  The preferred method of getting
00399             // a device description is to call RequestDeviceDescription().  This function may
00400             // be used on mounted devices - once a device is mounted its device description is cached.
00401 
00402             // only works if the deviceUUID is for a device that is a media server
00403         virtual bool UnmountDevice(const CascadeString & deviceUUID);
00404         virtual bool IsDeviceMounted(const CascadeString & deviceUUID);
00405 
00406         virtual bool AddDeviceToPersistentMountList(const CascadeString & deviceUUID);
00407         virtual bool RemoveDeviceFromPersistentMountList(const CascadeString & deviceUUID);
00408         virtual bool RemoveAllDevicesFromPersistentMountList();
00409         virtual bool IsDeviceInPersistentMountList(const CascadeString & deviceUUID);
00410 
00411         typedef bool (MountListEnumCallback)(const CascadeString & deviceUUID, void * pClientData);
00412         virtual bool EnumerateMountedDevices(MountListEnumCallback * pCallback, void * pClientData);
00413         virtual bool EnumeratePersistentMountList(MountListEnumCallback * pCallback, void * pClientData);
00414         virtual bool IsDeviceOnline(const CascadeString & deviceUUID);
00415  
00416         virtual bool IsWindowsMediaConnect(const DeviceDescription & deviceDescription);
00417         
00418         static const char * MediaServerDeviceType();
00419             // returns "schemas-upnp-org:device:MediaServer:1"
00420 
00421         TransactionResult GetLastTransactionResult();
00422         static const char * TransactionResultToString(TransactionResult result);
00423 
00424 private:
00425     virtual bool OnWormholeMessage(const CascadeMessage & message);
00426 private:
00427     UPnP * m_pUPnP;
00428 #else 
00429 public:
00430     virtual bool InitiateUPnPSearch(const CascadeString & searchTerm);
00431         // InitiateUPnPSearch() will send out a UPnP multicast search
00432         // request to the network using the searchTerm given.  Search
00433         // results will be routed asynchronously to the virtual function
00434         // OnSearchResult().  Clients will only see active devices in
00435         // their OnSearchResult() functions; to catch devices going 
00436         // off-line, monitor the OnStatusChange() function, below.
00437         // Search results will continue to be routed to the CascadeUPnP
00438         // object for its entire lifetime.  Returns false if search
00439         // could not be initiated, usually due to improperly formed
00440         // search term.
00441         //
00442         // The searchTerm may have one of the following forms:
00443         //   "ssdp:all"         - search for all UPnP devices
00444         //   "upnp:rootdevice"  - search for all root devices
00445         //   "uuid:<theUUID>"   - search for a specific device (by UUID)
00446         //   "urn:<theURN>"     - search for devices of a certain type
00447         //                        (e.g., "urn:schemas-upnp-org:device:<devType>")
00448         //
00449         // NOTE: only devices are currently searchable via the "urn:" specifier
00450         // currently, although the UPnP spec allows searching for services as well.
00451         //
00452         // NOTE: Each CascadeUPnP instance can only initiate one search at
00453         // a time.
00454         //
00455         // TODO: maybe return a search id and allow cancellation.
00456         
00457     virtual bool GetDeviceDescription(const Device & device,
00458             DeviceDescription & deviceDescriptionToSet, 
00459             u32 nTimeoutMS = 5000);
00460         // GetDeviceDescription() will query the device for its device
00461         // description XML document, parse it, and provide you with the
00462         // results in the DeviceDescription structure.  Returns false on
00463         // failure or timeout.
00464         //
00465         // Use GetDeviceDescriptionAsync() if you would prefer an asynchronous
00466         // version of this function.
00467     
00468     virtual bool GetDeviceDescriptionAsync(const Device & device);
00469         // GetDeviceDescriptionAsync() queries a device for its device
00470         // description XML document, parses it, and will notify you
00471         // when complete by calling your OnDeviceDescriptionComplete()
00472         // virtual function.  You may queue up as many description
00473         // requests as you want, but they might not execute at the
00474         // same time depending on network resource availibility.
00475         // There is a 30 second timeout for all requests once they
00476         // hit the network, so you are guaranteed a callback eventually.
00477         // Returns false if failure queing request.
00478         //
00479         // Use GetDeviceDescription() if you would prefer a synchronous
00480         // (blocking) version of this function.
00481             
00482 public:
00483     virtual void OnSearchResult(const Device & device);
00484         // Virtual client function for processing search results after
00485         // initiating a search with InitiateUPnPSearch().
00486     
00487     virtual void OnStatusChange(const Device & device);
00488         // Virtual client function for processing of UPnP status changes
00489         // multicasted on the local network.  There is no filtering of
00490         // device types; the client should ignore updates to devices it
00491         // is not interested in.
00492         //
00493         // TODO: should we allow clients to register for updates only
00494         // about some class of devices?
00495         
00496     virtual void OnDeviceDescriptionComplete(bool bSuccess, const Device & device, const DeviceDescription & deviceDescription);
00497         // Virtual client function for processing results of
00498         // GetDeviceDescriptionAsync().
00499 #endif
00500 };
00501 
00502 #endif // _ROKU_INCLUDE_CASCADE_NET_CASCADEUPNP_H
00503 
00505 //  LOG
00507 //  22-Sep-04   dsletten        created
00508 //  08-Oct-04   dsletten    increased default timeout for GetDeviceDescription()
00509 //  30-Nov-04   dsletten    added GetDeviceDescriptionAsync() and callback
00510 //  10-Dec-04   dwoodward   added deschutes implementation
00511 //  19-Jan-04   dwoodward   added GetCachedDeviceDescription(), GetDeviceFromUUID()

Generated on Sun Jul 24 14:27:17 2005 for Cascade Library by  doxygen 1.4.1