#if !defined(RESIP_SDPCONTENTS_HXX) #define RESIP_SDPCONTENTS_HXX #include #include #include #include "resip/stack/Contents.hxx" #include "resip/stack/Uri.hxx" #include "rutil/Data.hxx" #include "rutil/HashMap.hxx" #include "rutil/HeapInstanceCounter.hxx" namespace resip { class SdpContents; class AttributeHelper { public: RESIP_HeapCount(AttributeHelper); AttributeHelper(); AttributeHelper(const AttributeHelper& rhs); AttributeHelper& operator=(const AttributeHelper& rhs); bool exists(const Data& key) const; const std::list& getValues(const Data& key) const; std::ostream& encode(std::ostream& s) const; void parse(ParseBuffer& pb); void addAttribute(const Data& key, const Data& value = Data::Empty); void clearAttribute(const Data& key); private: HashMap< Data, std::list > mAttributes; }; class SdpContents : public Contents { public: RESIP_HeapCount(SdpContents); typedef enum {IP4=1, IP6} AddrType; static const SdpContents Empty; class Session; class Session { public: class Medium; class Codec { public: Codec() : mName(), mRate(0), mPayloadType(-1) {} Codec(const Data& name, unsigned long rate, const Data& parameters = Data::Empty); Codec(const Data& name, int payloadType, int rate=8000); Codec(const Codec& rhs); Codec& operator=(const Codec& codec); void parse(ParseBuffer& pb, const SdpContents::Session::Medium& medium, int payLoadType); const Data& getName() const; int getRate() const; int payloadType() const {return mPayloadType;} int& payloadType() {return mPayloadType;} const Data& parameters() const {return mParameters;} Data& parameters() {return mParameters;} static const Codec ULaw_8000; static const Codec ALaw_8000; static const Codec G729_8000; static const Codec G723_8000; static const Codec GSM_8000; static const Codec TelephoneEvent; static const Codec FrfDialedDigit; typedef HashMap CodecMap; // "static" payload types as defined in RFC 3551. // Maps payload type (number) to Codec definition. static CodecMap& getStaticCodecs(); friend bool operator==(const Codec&, const Codec&); private: Data mName; unsigned long mRate; int mPayloadType; Data mParameters; static std::auto_ptr sStaticCodecs; static bool sStaticCodecsCreated; friend std::ostream& operator<<(std::ostream&, const Codec&); }; class Origin { public: Origin(const Data& user, const UInt64& sessionId, const UInt64& version, AddrType addr, const Data& address); Origin(const Origin& rhs); Origin& operator=(const Origin& rhs); void parse(ParseBuffer& pb); std::ostream& encode(std::ostream&) const; const UInt64& getSessionId() const {return mSessionId;} UInt64& getSessionId() { return mSessionId; } const UInt64& getVersion() const {return mVersion;} UInt64& getVersion() { return mVersion; } const Data& user() const {return mUser;} Data& user() {return mUser;} AddrType getAddressType() const {return mAddrType;} const Data& getAddress() const {return mAddress;} void setAddress(const Data& host, AddrType type = IP4); private: Origin(); Data mUser; UInt64 mSessionId; UInt64 mVersion; AddrType mAddrType; Data mAddress; friend class Session; }; class Email { public: Email(const Data& address, const Data& freeText); Email(const Email& rhs); Email& operator=(const Email& rhs); void parse(ParseBuffer& pb); std::ostream& encode(std::ostream&) const; const Data& getAddress() const {return mAddress;} const Data& getFreeText() const {return mFreeText;} private: Email() {} Data mAddress; Data mFreeText; friend class Session; }; class Phone { public: Phone(const Data& number, const Data& freeText); Phone(const Phone& rhs); Phone& operator=(const Phone& rhs); void parse(ParseBuffer& pb); std::ostream& encode(std::ostream&) const; const Data& getNumber() const {return mNumber;} const Data& getFreeText() const {return mFreeText;} private: Phone() {} Data mNumber; Data mFreeText; friend class Session; }; class Connection { public: Connection(AddrType addType, const Data& address, unsigned long ttl = 0); Connection(const Connection& rhs); Connection& operator=(const Connection& rhs); void parse(ParseBuffer& pb); std::ostream& encode(std::ostream&) const; AddrType getAddressType() const {return mAddrType;} const Data& getAddress() const {return mAddress;} void setAddress(const Data& host, AddrType type = IP4); unsigned long ttl() const {return mTTL;} unsigned long& ttl() {return mTTL;} private: Connection(); AddrType mAddrType; Data mAddress; unsigned long mTTL; friend class Session; friend class Medium; }; class Bandwidth { public: Bandwidth(const Data& modifier, unsigned long kbPerSecond); Bandwidth(const Bandwidth& rhs); Bandwidth& operator=(const Bandwidth& rhs); void parse(ParseBuffer& pb); std::ostream& encode(std::ostream&) const; const Data& modifier() const {return mModifier;} Data modifier() {return mModifier;} unsigned long kbPerSecond() const {return mKbPerSecond;} unsigned long& kbPerSecond() {return mKbPerSecond;} private: Bandwidth() {} Data mModifier; unsigned long mKbPerSecond; friend class Session; friend class Medium; }; class Time { public: Time(unsigned long start, unsigned long stop); Time(const Time& rhs); Time& operator=(const Time& rhs); void parse(ParseBuffer& pb); std::ostream& encode(std::ostream&) const; class Repeat { public: Repeat(unsigned long interval, unsigned long duration, std::list offsets); void parse(ParseBuffer& pb); std::ostream& encode(std::ostream&) const; unsigned long getInterval() const {return mInterval;} unsigned long getDuration() const {return mDuration;} const std::list getOffsets() const {return mOffsets;} private: Repeat() {} unsigned long mInterval; unsigned long mDuration; std::list mOffsets; friend class Time; }; void addRepeat(const Repeat& repeat); unsigned long getStart() const {return mStart;} unsigned long getStop() const {return mStop;} const std::list& getRepeats() const {return mRepeats;} private: Time() {} unsigned long mStart; unsigned long mStop; std::list mRepeats; friend class Session; }; class Timezones { public: class Adjustment { public: Adjustment(unsigned long time, int offset); Adjustment(const Adjustment& rhs); Adjustment& operator=(const Adjustment& rhs); unsigned long time; int offset; }; Timezones(); Timezones(const Timezones& rhs); Timezones& operator=(const Timezones& rhs); void parse(ParseBuffer& pb); std::ostream& encode(std::ostream&) const; void addAdjustment(const Adjustment& adjusment); const std::list& getAdjustments() const {return mAdjustments; } private: std::list mAdjustments; }; class Encryption { public: typedef enum {NoEncryption = 0, Prompt, Clear, Base64, UriKey} KeyType; Encryption(const KeyType& method, const Data& key); Encryption(const Encryption& rhs); Encryption& operator=(const Encryption& rhs); void parse(ParseBuffer& pb); std::ostream& encode(std::ostream&) const; const KeyType& getMethod() const {return mMethod;} const KeyType& method() const {return mMethod;} KeyType& method() {return mMethod;} const Data& getKey() const {return mKey;} const Data& key() const {return mKey;} Data& key() {return mKey;} Encryption(); private: KeyType mMethod; Data mKey; }; class Medium { public: Medium(); Medium(const Medium& rhs); Medium(const Data& name, unsigned long port, unsigned long multicast, const Data& protocol); Medium& operator=(const Medium& rhs); void parse(ParseBuffer& pb); std::ostream& encode(std::ostream&) const; void addFormat(const Data& format); void setConnection(const Connection& connection); void addConnection(const Connection& connection); void setBandwidth(const Bandwidth& bandwidth); void addBandwidth(const Bandwidth& bandwidth); void addAttribute(const Data& key, const Data& value = Data::Empty); const Data& name() const {return mName;} Data& name() {return mName;} int port() const {return mPort;} unsigned long& port() {return mPort;} void setPort(int port); int multicast() const {return mMulticast;} unsigned long& multicast() {return mMulticast;} const Data& protocol() const {return mProtocol;} Data& protocol() {return mProtocol;} // preferred codec/format interface const std::list& codecs() const; std::list& codecs(); void clearCodecs(); void addCodec(const Codec& codec); const std::list& getFormats() const {return mFormats;} const Data& information() const {return mInformation;} Data& information() {return mInformation;} const std::list& bandwidths() const {return mBandwidths;} std::list& bandwidths() {return mBandwidths;} // from session if empty const std::list getConnections() const; // does not include session connections std::list& getMediumConnections() {return mConnections;} const Encryption& getEncryption() const {return mEncryption;} const Encryption& encryption() const {return mEncryption;} Encryption& encryption() {return mEncryption;} bool exists(const Data& key) const; const std::list& getValues(const Data& key) const; void clearAttribute(const Data& key); const Codec& findFirstMatchingCodecs(const std::list& codecs) const; const Codec& findFirstMatchingCodecs(const Medium& medium) const { if (&medium == this) return codecs().front(); else return findFirstMatchingCodecs(medium.codecs()); } int findTelephoneEventPayloadType() const; private: void setSession(Session* session); Session* mSession; Data mName; unsigned long mPort; unsigned long mMulticast; Data mProtocol; mutable std::list mFormats; mutable std::list mCodecs; Data mTransport; Data mInformation; std::list mConnections; std::list mBandwidths; Encryption mEncryption; mutable AttributeHelper mAttributeHelper; mutable bool mRtpMapDone; typedef HashMap RtpMap; mutable RtpMap mRtpMap; friend class Session; }; Session(int version, const Origin& origin, const Data& name); Session() : mVersion(0) {} Session(const Session& rhs); Session& operator=(const Session& rhs); void parse(ParseBuffer& pb); std::ostream& encode(std::ostream&) const; int version() const {return mVersion;} int& version() {return mVersion;} const Origin& origin() const {return mOrigin;} Origin& origin() {return mOrigin;} const Data& name() const {return mName;} Data& name() {return mName;} const Data& information() const {return mInformation;} Data& information() {return mInformation;} const Uri& uri() const {return mUri;} Uri& uri() {return mUri;} const std::list& getEmails() const {return mEmails;} const std::list& getPhones() const {return mPhones;} const Connection& connection() const {return mConnection;} Connection& connection() {return mConnection;} // !dlb! optional? bool isConnection() { return mConnection.mAddress != Data::Empty; } const std::list& bandwidths() const {return mBandwidths;} std::list& bandwidths() {return mBandwidths;} const std::list