00001
00024 #ifndef __YATEMGCP_H
00025 #define __YATEMGCP_H
00026
00027 #include <yateclass.h>
00028 #include <yatemime.h>
00029
00030 #ifdef _WINDOWS
00031
00032 #ifdef LIBYMGCP_EXPORTS
00033 #define YMGCP_API __declspec(dllexport)
00034 #else
00035 #ifndef LIBYMGCP_STATIC
00036 #define YMGCP_API __declspec(dllimport)
00037 #endif
00038 #endif
00039
00040 #endif
00041
00042 #ifndef YMGCP_API
00043 #define YMGCP_API
00044 #endif
00045
00049 namespace TelEngine {
00050
00051 class MGCPMessage;
00052 class MGCPTransaction;
00053 class MGCPEpInfo;
00054 class MGCPEndpoint;
00055 class MGCPEvent;
00056 class MGCPEngine;
00057
00063 class YMGCP_API MGCPMessage : public RefObject
00064 {
00065 friend class MGCPTransaction;
00066 public:
00077 MGCPMessage(MGCPEngine* engine, const char* name, const char* ep, const char* ver = "MGCP 1.0");
00078
00087 MGCPMessage(MGCPTransaction* trans, unsigned int code, const char* comment = 0);
00088
00092 virtual ~MGCPMessage();
00093
00098 inline bool valid() const
00099 { return m_valid; }
00100
00105 inline const String& name() const
00106 { return m_name; }
00107
00112 inline int code() const
00113 { return m_code; }
00114
00119 inline const String& version() const
00120 { return m_version; }
00121
00126 inline const String& comment() const
00127 { return m_comment; }
00128
00133 inline bool isCommand() const
00134 { return code() < 0; }
00135
00140 inline bool isResponse() const
00141 { return 100 <= code(); }
00142
00147 inline bool isAck() const
00148 { return 0 <= code() && code() <= 99; }
00149
00154 inline unsigned int transactionId() const
00155 { return m_transaction; }
00156
00161 inline const String& endpointId() const
00162 { return m_endpoint; }
00163
00169 void toString(String& dest) const;
00170
00183 static bool parse(MGCPEngine* engine, ObjList& dest,
00184 const unsigned char* buffer, unsigned int len,
00185 const char* sdpType = "application/sdp");
00186
00190 NamedList params;
00191
00195 ObjList sdp;
00196
00197 protected:
00208 MGCPMessage(MGCPEngine* engine, const char* name, int code,
00209 unsigned int transId, const char* epId, const char* ver);
00210
00211 private:
00212 MGCPMessage() : params("") {}
00213
00214 static MGCPMessage* decodeMessage(const char* line, unsigned int len, unsigned int& trans,
00215 String& error, MGCPEngine* engine);
00216
00217 static bool decodeParams(const unsigned char* buffer, unsigned int len,
00218 unsigned int& crt, MGCPMessage* msg, String& error, MGCPEngine* engine);
00219
00220 String m_name;
00221 bool m_valid;
00222 int m_code;
00223 unsigned int m_transaction;
00224 String m_endpoint;
00225 String m_version;
00226 String m_comment;
00227 };
00228
00233 class YMGCP_API MGCPTransaction : public RefObject, public Mutex
00234 {
00235 friend class MGCPEngine;
00236 friend class MGCPEvent;
00237 public:
00241 enum State {
00242 Invalid = 0,
00243 Initiated = 1,
00244 Trying = 2,
00245 Responded = 3,
00246 Ack = 4,
00247 Destroying = 5,
00248 };
00249
00257 MGCPTransaction(MGCPEngine* engine, MGCPMessage* msg, bool outgoing,
00258 const SocketAddr& address);
00259
00263 virtual ~MGCPTransaction();
00264
00269 inline State state() const
00270 { return m_state; }
00271
00276 inline unsigned int id() const
00277 { return m_id; }
00278
00283 inline bool outgoing() const
00284 { return m_outgoing; }
00285
00290 inline const String& ep() const
00291 { return m_endpoint; }
00292
00297 const SocketAddr& addr() const
00298 { return m_address; }
00299
00304 inline MGCPEngine* engine()
00305 { return m_engine; }
00306
00311 inline const MGCPMessage* initial() const
00312 { return m_cmd; }
00313
00318 inline const MGCPMessage* msgProvisional() const
00319 { return m_provisional; }
00320
00325 inline const MGCPMessage* msgResponse() const
00326 { return m_response; }
00327
00332 inline const MGCPMessage* msgAck() const
00333 { return m_ack; }
00334
00339 inline bool timeout() const
00340 { return m_timeout; }
00341
00346 inline void* userData() const
00347 { return m_private; }
00348
00353 inline void userData(void* data)
00354 { m_private = data; }
00355
00361 MGCPEvent* getEvent(u_int64_t time = Time());
00362
00369 bool sendProvisional(int code = 100, const char* comment = 0);
00370
00378 inline bool setResponse(int code, const char* comment = 0)
00379 { return setResponse(new MGCPMessage(this,code,comment)); }
00380
00391 bool setResponse(int code, const NamedList* params, MimeSdpBody* sdp1 = 0,
00392 MimeSdpBody* sdp2 = 0);
00393
00400 bool setResponse(MGCPMessage* msg);
00401
00402 protected:
00406 virtual void destroyed();
00407
00412 void processMessage(MGCPMessage* msg);
00413
00419 MGCPEvent* checkTimeout(u_int64_t time);
00420
00425 void eventTerminated(MGCPEvent* event);
00426
00431 void changeState(State newState);
00432
00437 void setProvisional(int code = 100);
00438
00443 void send(MGCPMessage* msg);
00444
00445 private:
00446 MGCPTransaction() {}
00447
00448
00449 MGCPEvent* checkResponse(u_int64_t time);
00450
00451 void initTimeout(u_int64_t time, bool extra);
00452
00453 MGCPEvent* terminate();
00454
00455 State m_state;
00456 unsigned int m_id;
00457 bool m_outgoing;
00458 SocketAddr m_address;
00459 MGCPEngine* m_engine;
00460 MGCPMessage* m_cmd;
00461 MGCPMessage* m_provisional;
00462 MGCPMessage* m_response;
00463 MGCPMessage* m_ack;
00464 MGCPEvent* m_lastEvent;
00465 String m_endpoint;
00466 u_int64_t m_nextRetrans;
00467 unsigned int m_crtRetransInterval;
00468 unsigned int m_retransCount;
00469 bool m_timeout;
00470 void* m_private;
00471 String m_debug;
00472 };
00473
00478 class YMGCP_API MGCPEndpointId
00479 {
00480 public:
00484 inline MGCPEndpointId()
00485 : m_port(0)
00486 {}
00487
00492 inline MGCPEndpointId(String& src)
00493 : m_port(0)
00494 { set(src); }
00495
00502 inline MGCPEndpointId(const char* endpoint, const char* host, int port)
00503 : m_port(0)
00504 { set(endpoint,host,port); }
00505
00510 inline const String& id() const
00511 { return m_id; }
00512
00517 inline const String& user() const
00518 { return m_endpoint; }
00519
00524 inline const String& host() const
00525 { return m_host; }
00526
00531 inline int port() const
00532 { return m_port; }
00533
00538 inline void port(int newPort)
00539 { set(m_endpoint,m_host,newPort); }
00540
00547 void set(const char* endpoint, const char* host, int port);
00548
00553 inline void set(String& src) {
00554 URI uri(src);
00555 set(uri.getUser(),uri.getHost(),uri.getPort());
00556 }
00557
00564 inline bool valid() const {
00565 return m_endpoint && m_endpoint.length() < 256 &&
00566 m_host && m_host.length() < 256;
00567 }
00568
00569 private:
00570 String m_id;
00571 String m_endpoint;
00572 String m_host;
00573 int m_port;
00574 };
00575
00580 class YMGCP_API MGCPEpInfo : public MGCPEndpointId, public GenObject
00581 {
00582 public:
00589 inline MGCPEpInfo(const char* endpoint, const char* host, int port)
00590 : MGCPEndpointId(endpoint,host,port), address(AF_INET) {
00591 address.host(host);
00592 address.port(port);
00593 }
00594
00599 virtual const String& toString() const
00600 { return id(); }
00601
00605 SocketAddr address;
00606 };
00607
00614 class YMGCP_API MGCPEndpoint : public RefObject, public MGCPEndpointId
00615 {
00616 public:
00625 MGCPEndpoint(MGCPEngine* engine, const char* user, const char* host, int port);
00626
00630 virtual ~MGCPEndpoint();
00631
00636 virtual const String& toString() const
00637 { return MGCPEndpointId::id(); }
00638
00643 inline MGCPEngine* engine()
00644 { return m_engine; }
00645
00656 MGCPEpInfo* append(const char* endpoint, const char* host, int port = 0);
00657
00661 inline void clear()
00662 { Lock lock(m_mutex); m_remote.clear(); }
00663
00669 MGCPEpInfo* find(const char* epId);
00670
00675 MGCPEpInfo* peer();
00676
00677 private:
00678 MGCPEngine* m_engine;
00679 Mutex m_mutex;
00680 ObjList m_remote;
00681 };
00682
00688 class YMGCP_API MGCPEvent
00689 {
00690 friend class MGCPTransaction;
00691 public:
00695 ~MGCPEvent();
00696
00701 inline MGCPTransaction* transaction()
00702 { return m_transaction; }
00703
00708 inline MGCPMessage* message() const
00709 { return m_message; }
00710
00711 protected:
00717 MGCPEvent(MGCPTransaction* trans, MGCPMessage* msg = 0);
00718
00719 private:
00720 MGCPTransaction* m_transaction;
00721 MGCPMessage* m_message;
00722 };
00723
00724 class MGCPPrivateThread;
00725
00735 class YMGCP_API MGCPEngine : public DebugEnabler, public Mutex
00736 {
00737 friend class MGCPPrivateThread;
00738 friend class MGCPTransaction;
00739 public:
00747 MGCPEngine(bool gateway, const char* name = 0, const NamedList* params = 0);
00748
00752 virtual ~MGCPEngine();
00753
00759 inline bool gateway() const
00760 { return m_gateway; }
00761
00766 inline const SocketAddr& address() const
00767 { return m_address; }
00768
00774 inline unsigned int maxRecvPacket() const
00775 { return m_maxRecvPacket; }
00776
00781 inline bool allowUnkCmd() const
00782 { return m_allowUnkCmd; }
00783
00788 inline unsigned int retransInterval() const
00789 { return m_retransInterval; }
00790
00795 inline unsigned int retransCount() const
00796 { return m_retransCount; }
00797
00802 inline u_int64_t extraTime() const
00803 { return m_extraTime; }
00804
00809 inline bool parseParamToLower() const
00810 { return m_parseParamToLower; }
00811
00816 inline bool provisional() const
00817 { return m_provisional; }
00818
00823 virtual void initialize(const NamedList& params);
00824
00830 inline bool knownCommand(const char* cmd)
00831 { Lock lock(this); return (m_knownCommands.find(cmd) != 0); }
00832
00837 void addCommand(const char* cmd);
00838
00843 void attach(MGCPEndpoint* ep);
00844
00852 void detach(MGCPEndpoint* ep, bool del = false, bool delTrans = false);
00853
00859 MGCPEndpoint* findEp(MGCPEndpoint* ep);
00860
00866 MGCPEndpoint* findEp(const char* epId);
00867
00874 MGCPTransaction* findTrans(unsigned int id, bool outgoing);
00875
00880 unsigned int getNextId();
00881
00889 MGCPTransaction* sendCommand(MGCPMessage* cmd, const SocketAddr& address);
00890
00898 bool receive(unsigned char* buffer, SocketAddr& addr);
00899
00908 bool process(u_int64_t time = Time());
00909
00913 void runReceive();
00914
00918 void runProcess();
00919
00925 MGCPEvent* getEvent(u_int64_t time = Time());
00926
00935 virtual bool processEvent(MGCPEvent* event);
00936
00946 virtual bool processEvent(MGCPTransaction* trans, MGCPMessage* msg, void* data);
00947
00954 void returnEvent(MGCPEvent* event);
00955
00965 void cleanup(bool gracefully = true, const char* text = "Shutdown");
00966
00973 static inline int defaultPort(bool gateway)
00974 { return gateway ? 2427 : 2727; }
00975
00979 static TokenDict mgcp_commands[];
00980
00984 static TokenDict mgcp_responses[];
00985
00993 static TokenDict mgcp_reasons[];
00994
00995 protected:
01002 bool sendData(const String& msg, const SocketAddr& address);
01003
01008 void appendTrans(MGCPTransaction* trans);
01009
01015 void removeTrans(MGCPTransaction* trans, bool del);
01016
01020 ObjList m_endpoints;
01021
01025 ObjList m_transactions;
01026
01027 private:
01028
01029 void appendThread(MGCPPrivateThread* thread);
01030
01031 void removeThread(MGCPPrivateThread* thread);
01032
01033
01034 unsigned int* decodeAck(const String& param, unsigned int & count);
01035
01036 bool m_gateway;
01037 bool m_initialized;
01038 unsigned int m_nextId;
01039 Socket m_socket;
01040 SocketAddr m_address;
01041 unsigned int m_maxRecvPacket;
01042 unsigned char* m_recvBuf;
01043 bool m_allowUnkCmd;
01044 unsigned int m_retransInterval;
01045 unsigned int m_retransCount;
01046 u_int64_t m_extraTime;
01047 bool m_parseParamToLower;
01048 bool m_provisional;
01049 ObjList m_knownCommands;
01050 ObjList m_threads;
01051 };
01052
01053 }
01054
01055 #endif
01056
01057