00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 #ifndef OPAL_H323_PECLIENT_H
00032 #define OPAL_H323_PECLIENT_H
00033 
00034 #ifdef P_USE_PRAGMA
00035 #pragma interface
00036 #endif
00037 
00038 #include <opal/buildopts.h>
00039 
00040 #if OPAL_H501
00041 
00042 #include <h323/h323annexg.h>
00043 #include <h323/h323ep.h>
00044 
00045 #include <ptlib/safecoll.h>
00046 
00047 
00048 class H323PeerElement;
00049 
00050 
00052 
00053 class H501Transaction : public H323Transaction
00054 {
00055     PCLASSINFO(H501Transaction, H323Transaction);
00056   public:
00057     H501Transaction(
00058       H323PeerElement & pe,
00059       const H501PDU & pdu,
00060       PBoolean hasReject
00061     );
00062 
00063     virtual H323TransactionPDU * CreateRIP(
00064       unsigned sequenceNumber,
00065       unsigned delay
00066     ) const;
00067 
00068     virtual H235Authenticator::ValidationResult ValidatePDU() const;
00069 
00070     H501_MessageCommonInfo & requestCommon;
00071     H501_MessageCommonInfo & confirmCommon;
00072 
00073   protected:
00074     H323PeerElement & peerElement;
00075 };
00076 
00077 
00079 
00080 class H501ServiceRequest : public H501Transaction
00081 {
00082     PCLASSINFO(H501ServiceRequest, H501Transaction);
00083   public:
00084     H501ServiceRequest(
00085       H323PeerElement & pe,
00086       const H501PDU & pdu
00087     );
00088 
00089 #if PTRACING
00090     virtual const char * GetName() const;
00091 #endif
00092     virtual void SetRejectReason(
00093       unsigned reasonCode
00094     );
00095 
00096     H501_ServiceRequest & srq;
00097     H501_ServiceConfirmation & scf;
00098     H501_ServiceRejection  & srj;
00099 
00100   protected:
00101     virtual Response OnHandlePDU();
00102 };
00103 
00104 
00106 
00107 class H501DescriptorUpdate : public H501Transaction
00108 {
00109     PCLASSINFO(H501DescriptorUpdate, H501Transaction);
00110   public:
00111     H501DescriptorUpdate(
00112       H323PeerElement & pe,
00113       const H501PDU & pdu
00114     );
00115 
00116 #if PTRACING
00117     virtual const char * GetName() const;
00118 #endif
00119     virtual void SetRejectReason(
00120       unsigned reasonCode
00121     );
00122 
00123     H501_DescriptorUpdate & du;
00124     H501_DescriptorUpdateAck & ack;
00125 
00126   protected:
00127     virtual Response OnHandlePDU();
00128 };
00129 
00130 
00132 
00133 class H501AccessRequest : public H501Transaction
00134 {
00135     PCLASSINFO(H501AccessRequest, H501Transaction);
00136   public:
00137     H501AccessRequest(
00138       H323PeerElement & pe,
00139       const H501PDU & pdu
00140     );
00141 
00142 #if PTRACING
00143     virtual const char * GetName() const;
00144 #endif
00145     virtual void SetRejectReason(
00146       unsigned reasonCode
00147     );
00148 
00149     H501_AccessRequest & arq;
00150     H501_AccessConfirmation & acf;
00151     H501_AccessRejection  & arj;
00152 
00153   protected:
00154     virtual Response OnHandlePDU();
00155 };
00156 
00157 
00159 
00160 class H323PeerElementDescriptor : public PSafeObject
00161 {
00162   PCLASSINFO(H323PeerElementDescriptor, PSafeObject);
00163   public:
00164     H323PeerElementDescriptor(const OpalGloballyUniqueID & _descriptorID)
00165       : descriptorID(_descriptorID), state(Dirty), creator(0)
00166     { }
00167 
00168     Comparison Compare(const PObject & obj) const;
00169 
00170     enum Options {
00171       Protocol_H323            = 0x0001,
00172       Protocol_Voice           = 0x0002,
00173       Protocol_Max             = 0x0002,
00174       Option_WildCard          = 0x0004,
00175       Option_SendAccessRequest = 0x0008,
00176       Option_NotAvailable      = 0x0010,
00177       Option_PrioritySet       = 0x0020,
00178       Option_PriorityMask      = 0x1fc0,
00179     };
00180 
00181     enum {
00182       HighestPriority          = 0,
00183       DefaultPriority          = 80,
00184       LowestPriority           = 127
00185     };
00186 
00187     static inline unsigned SetPriorityOption(unsigned pri)     { return Option_PrioritySet | ((pri & 0x7f) << 6); }
00188     static inline unsigned GetPriorityOption(unsigned options) { return (options & Option_PrioritySet) != 0 ? ((options >> 6) & 0x7f) : (int)DefaultPriority; }
00189 
00190     void CopyTo(H501_Descriptor & descriptor);
00191     static PBoolean CopyToAddressTemplate(H501_AddressTemplate & addressTemplates, 
00192                                    const H225_EndpointType & ep, 
00193                            const H225_ArrayOf_AliasAddress & aliases, 
00194                            const H225_ArrayOf_AliasAddress & transportAddress, 
00195                                                     unsigned options = H323PeerElementDescriptor::Protocol_H323);
00196 
00197     static void SetProtocolList(H501_ArrayOf_SupportedProtocols & h501Protocols, unsigned protocols);
00198     static unsigned GetProtocolList(const H501_ArrayOf_SupportedProtocols & h501Protocols);
00199 
00200     OpalGloballyUniqueID descriptorID;
00201 
00202     PBoolean ContainsNonexistent();
00203 
00204     enum States {
00205       Clean,
00206       Dirty,
00207       Deleted
00208     } state;
00209 
00210     H501_ArrayOf_AddressTemplate addressTemplates;
00211     PString gatekeeperID;
00212     PTime lastChanged;
00213     POrdinalKey creator;
00214 };
00215 
00216 
00218 
00219 class H323PeerElementServiceRelationship : public PSafeObject
00220 {
00221     PCLASSINFO(H323PeerElementServiceRelationship, PSafeObject);
00222   public:
00223     H323PeerElementServiceRelationship()
00224       : ordinal(0)
00225       { }
00226 
00227     H323PeerElementServiceRelationship(const OpalGloballyUniqueID & _serviceID)
00228       : serviceID(_serviceID), ordinal(0)
00229       { }
00230 
00231     Comparison Compare(const PObject & obj) const
00232       { return serviceID.Compare(((H323PeerElementServiceRelationship&)obj).serviceID); }
00233 
00234     OpalGloballyUniqueID serviceID;
00235     POrdinalKey ordinal;
00236     H323TransportAddress peer;
00237     PString name;
00238     PTime createdTime;
00239     PTime lastUpdateTime;
00240     PTime expireTime;
00241 };
00242 
00243 
00245 
00248 class H323PeerElement : public H323_AnnexG
00249 {
00250     PCLASSINFO(H323PeerElement, H323_AnnexG);
00251   public:
00256     H323PeerElement(
00257       H323EndPoint & endpoint,  
00258       H323Transport * transport = NULL
00259     );
00260     H323PeerElement(
00261       H323EndPoint & endpoint,  
00262       const H323TransportAddress & addr
00263     );
00264 
00267     ~H323PeerElement();
00269 
00270     enum Error {
00271       Confirmed,
00272       Rejected,
00273       NoResponse,
00274       NoServiceRelationship,
00275       ServiceRelationshipReestablished
00276     };
00277 
00278     enum {
00279       LocalServiceRelationshipOrdinal  = 0,
00280       NoServiceRelationshipOrdinal     = 1,
00281       RemoteServiceRelationshipOrdinal = 2
00282     };
00283 
00288     void PrintOn(
00289       ostream & strm    
00290     ) const;
00292 
00293     PSafePtr<H323PeerElementDescriptor> GetFirstDescriptor(
00294       PSafetyMode mode = PSafeReference
00295     ) { return PSafePtr<H323PeerElementDescriptor>(descriptors, mode); }
00296 
00297     PSafePtr<H323PeerElementServiceRelationship> GetFirstLocalServiceRelationship(
00298       PSafetyMode mode = PSafeReference
00299     ) { return PSafePtr<H323PeerElementServiceRelationship>(localServiceRelationships, mode); }
00300 
00301     PSafePtr<H323PeerElementServiceRelationship> GetFirstRemoteServiceRelationship(
00302       PSafetyMode mode = PSafeReference
00303     ) { return PSafePtr<H323PeerElementServiceRelationship>(remoteServiceRelationships, mode); }
00304 
00305     void SetLocalName(const PString & name);
00306     PString GetLocalName() const;
00307 
00308     void SetDomainName(const PString & name);
00309     PString GetDomainName() const;
00310 
00311     
00312 
00313 
00314 
00317     PBoolean SetOnlyServiceRelationship(const PString & peer, PBoolean keepTrying = PTrue);
00318     PBoolean AddServiceRelationship(const H323TransportAddress & peer, PBoolean keepTrying = PTrue);
00319     PBoolean AddServiceRelationship(const H323TransportAddress & peer, OpalGloballyUniqueID & serviceID, PBoolean keepTrying = PTrue);
00320     PBoolean RemoveServiceRelationship(const OpalGloballyUniqueID & serviceID, int reason = H501_ServiceReleaseReason::e_terminated);
00321     PBoolean RemoveServiceRelationship(const H323TransportAddress & peer, int reason = H501_ServiceReleaseReason::e_terminated);
00322     PBoolean RemoveAllServiceRelationships();
00323 
00324     Error ServiceRequestByAddr(const H323TransportAddress & peer);
00325     Error ServiceRequestByAddr(const H323TransportAddress & peer, OpalGloballyUniqueID & serviceID);
00326     Error ServiceRequestByID(OpalGloballyUniqueID & serviceID);
00327 
00330     PBoolean ServiceRelease(const OpalGloballyUniqueID & serviceID, unsigned reason);
00331 
00332     
00333 
00334 
00335 
00336     PBoolean AddDescriptor(
00337       const OpalGloballyUniqueID & descriptorID,
00338       const PStringArray & aliases, 
00339       const H323TransportAddressArray & transportAddrs, 
00340       unsigned options = H323PeerElementDescriptor::Protocol_H323, 
00341       PBoolean now = PFalse
00342     );
00343 
00344     PBoolean AddDescriptor(
00345       const OpalGloballyUniqueID & descriptorID,
00346       const H225_ArrayOf_AliasAddress & aliases, 
00347       const H323TransportAddressArray & transportAddrs, 
00348       unsigned options = H323PeerElementDescriptor::Protocol_H323, 
00349       PBoolean now = PFalse
00350     );
00351 
00352     PBoolean AddDescriptor(
00353       const OpalGloballyUniqueID & descriptorID,
00354       const H225_ArrayOf_AliasAddress & aliases, 
00355       const H225_ArrayOf_AliasAddress & transportAddr, 
00356       unsigned options = H323PeerElementDescriptor::Protocol_H323, 
00357       PBoolean now = PFalse
00358     );
00359 
00360     PBoolean AddDescriptor(
00361       const OpalGloballyUniqueID & descriptorID,
00362       const POrdinalKey & creator,
00363       const H225_ArrayOf_AliasAddress & alias, 
00364       const H225_ArrayOf_AliasAddress & transportAddresses,
00365       unsigned options = H323PeerElementDescriptor::Protocol_H323,
00366       PBoolean now = PFalse
00367     );
00368 
00369     PBoolean AddDescriptor(
00370       const OpalGloballyUniqueID & descriptorID,
00371       const POrdinalKey & creator,
00372       const H501_ArrayOf_AddressTemplate & addressTemplates,
00373       const PTime & updateTime,
00374       PBoolean now = PFalse
00375     );
00376 
00379     PBoolean DeleteDescriptor(const PString & alias, PBoolean now = PFalse);
00380     PBoolean DeleteDescriptor(const H225_AliasAddress & alias, PBoolean now = PFalse);
00381     PBoolean DeleteDescriptor(const OpalGloballyUniqueID & descriptorID, PBoolean now = PFalse);
00382 
00385     PBoolean AccessRequest(
00386       const PString & searchAlias,
00387       PStringArray & destAliases, 
00388       H323TransportAddress & transportAddress,
00389       unsigned options = H323PeerElementDescriptor::Protocol_H323
00390     );
00391 
00392     PBoolean AccessRequest(
00393       const PString & searchAlias,
00394       H225_ArrayOf_AliasAddress & destAliases,
00395       H323TransportAddress & transportAddress,
00396       unsigned options = H323PeerElementDescriptor::Protocol_H323
00397     );
00398 
00399     PBoolean AccessRequest(
00400       const H225_AliasAddress & searchAlias,
00401       H225_ArrayOf_AliasAddress & destAliases,
00402       H323TransportAddress & transportAddress,
00403       unsigned options = H323PeerElementDescriptor::Protocol_H323
00404     );
00405 
00406     PBoolean AccessRequest(
00407       const H225_AliasAddress & alias,
00408       H225_ArrayOf_AliasAddress & destAliases,
00409       H225_AliasAddress & transportAddress,
00410       unsigned options = H323PeerElementDescriptor::Protocol_H323
00411     );
00412 
00413     
00414 
00415 
00416     PBoolean UpdateDescriptor(H323PeerElementDescriptor * descriptor);
00417     PBoolean UpdateDescriptor(H323PeerElementDescriptor * descriptor, H501_UpdateInformation_updateType::Choices updateType);
00418 
00419 
00420     Error SendUpdateDescriptorByID(const OpalGloballyUniqueID & serviceID, 
00421                                     H323PeerElementDescriptor * descriptor, 
00422                      H501_UpdateInformation_updateType::Choices updateType);
00423 
00424     Error SendUpdateDescriptorByAddr(const H323TransportAddress & peer, 
00425                                       H323PeerElementDescriptor * descriptor, 
00426                        H501_UpdateInformation_updateType::Choices updateType);
00427 
00428     Error SendAccessRequestByID(const OpalGloballyUniqueID & peerID, 
00429                                                    H501PDU & request, 
00430                                                    H501PDU & confirmPDU);
00431 
00432     Error SendAccessRequestByAddr(const H323TransportAddress & peerAddr, 
00433                                                      H501PDU & request, 
00434                                                      H501PDU & confirmPDU);
00435 
00436 
00437     
00438 
00439 
00440 
00441     PBoolean MakeRequest(H323_AnnexG::Request & request);
00442 
00443     virtual void OnAddServiceRelationship(const H323TransportAddress &) { }
00444     virtual void OnRemoveServiceRelationship(const H323TransportAddress &) { }
00445 
00446     virtual void OnNewDescriptor(const H323PeerElementDescriptor &) { }
00447     virtual void OnUpdateDescriptor(const H323PeerElementDescriptor &) { }
00448     virtual void OnRemoveDescriptor(const H323PeerElementDescriptor &) { }
00449 
00450     virtual H323Transaction::Response OnServiceRequest(H501ServiceRequest & info);
00451     virtual H323Transaction::Response OnDescriptorUpdate(H501DescriptorUpdate & info);
00452     virtual H323Transaction::Response OnAccessRequest(H501AccessRequest & info);
00453 
00454     PBoolean OnReceiveServiceRequest(const H501PDU & pdu, const H501_ServiceRequest & pduBody);
00455     PBoolean OnReceiveServiceConfirmation(const H501PDU & pdu, const H501_ServiceConfirmation & pduBody);
00456 
00457     PBoolean OnReceiveDescriptorUpdate(const H501PDU & pdu, const H501_DescriptorUpdate & pduBody);
00458     PBoolean OnReceiveDescriptorUpdateACK(const H501PDU & pdu, const H501_DescriptorUpdateAck & pduBody);
00459 
00460     PBoolean OnReceiveAccessRequest(const H501PDU & pdu, const H501_AccessRequest & pduBody);
00461     PBoolean OnReceiveAccessConfirmation (const H501PDU & pdu, const H501_AccessConfirmation & pduBody);
00462     PBoolean OnReceiveAccessRejection(const H501PDU & pdu,     const H501_AccessRejection & pduBody);
00463 
00464     class AliasKey : public H225_AliasAddress
00465     {
00466       public:
00467         AliasKey(const H225_AliasAddress & _alias, const OpalGloballyUniqueID & _id, PINDEX _pos, PBoolean _wild = PFalse)
00468           : H225_AliasAddress(_alias), id(_id), pos(_pos), wild(_wild)
00469         { }
00470 
00471         OpalGloballyUniqueID id;
00472         PINDEX pos;
00473         PBoolean wild;
00474     };
00475 
00476   protected:
00477     void Construct();
00478 
00479     Error SendUpdateDescriptor(              H501PDU & pdu,  
00480                           const H323TransportAddress & peer, 
00481                            H323PeerElementDescriptor * descriptor,
00482             H501_UpdateInformation_updateType::Choices updateType);
00483 
00484     PBoolean OnRemoteServiceRelationshipDisappeared(OpalGloballyUniqueID & serviceID, const H323TransportAddress & peer);
00485     void InternalRemoveServiceRelationship(const H323TransportAddress & peer);
00486     H323Transaction::Response HandleServiceRequest(H501ServiceRequest & info);
00487 
00488     virtual H323PeerElementDescriptor          * CreateDescriptor(const OpalGloballyUniqueID & descriptorID);
00489     virtual H323PeerElementServiceRelationship * CreateServiceRelationship();
00490     virtual AliasKey                           * CreateAliasKey(const H225_AliasAddress & alias, const OpalGloballyUniqueID & id, PINDEX pos, PBoolean wild = PFalse);
00491 
00492     void RemoveDescriptorInformation(const H501_ArrayOf_AddressTemplate & addressTemplates);
00493 
00494     PDECLARE_NOTIFIER(PThread, H323PeerElement, MonitorMain);
00495     PDECLARE_NOTIFIER(PThread, H323PeerElement, UpdateAllDescriptors);
00496     PDECLARE_NOTIFIER(PTimer, H323PeerElement, TickleMonitor);
00497 
00498     PMutex localNameMutex;
00499     PString localIdentifier;
00500     PString domainName;
00501 
00502     PSemaphore requestMutex;
00503     PThread  * monitor;
00504     PBoolean       monitorStop;
00505     PSyncPoint monitorTickle;
00506 
00507     PMutex basePeerOrdinalMutex;
00508     PINDEX basePeerOrdinal;
00509 
00510     
00511     PSafeSortedList<H323PeerElementServiceRelationship> localServiceRelationships;
00512     PMutex localPeerListMutex;
00513     POrdinalSet localServiceOrdinals;
00514 
00515     
00516     PMutex remotePeerListMutex;
00517     PSafeSortedList<H323PeerElementServiceRelationship> remoteServiceRelationships;
00518     PStringToString remotePeerAddrToServiceID;
00519     PDICTIONARY(StringToOrdinalKey, PString, POrdinalKey);
00520     StringToOrdinalKey remotePeerAddrToOrdinalKey;
00521 
00522     PSafeSortedList<H323PeerElementDescriptor> descriptors;
00523 
00524     PSORTED_LIST(AliasKeyList, H225_AliasAddress);
00525 
00526     PMutex aliasMutex;
00527     AliasKeyList transportAddressToDescriptorID;
00528     AliasKeyList specificAliasToDescriptorID;
00529     AliasKeyList wildcardAliasToDescriptorID;
00530 };
00531 
00532 
00533 #endif // OPAL_H501
00534 
00535 #endif // OPAL_H323_PECLIENT_H
00536 
00537