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 ackRequest(bool request)
00347 { m_ackRequest = request; }
00348
00353 inline void* userData() const
00354 { return m_private; }
00355
00360 inline void userData(void* data)
00361 { m_private = data; }
00362
00368 MGCPEvent* getEvent(u_int64_t time = Time());
00369
00376 bool sendProvisional(int code = 100, const char* comment = 0);
00377
00385 inline bool setResponse(int code, const char* comment = 0)
00386 { return setResponse(new MGCPMessage(this,code,comment)); }
00387
00398 bool setResponse(int code, const NamedList* params, MimeSdpBody* sdp1 = 0,
00399 MimeSdpBody* sdp2 = 0);
00400
00407 bool setResponse(MGCPMessage* msg);
00408
00409 protected:
00413 virtual void destroyed();
00414
00419 void processMessage(MGCPMessage* msg);
00420
00426 MGCPEvent* checkTimeout(u_int64_t time);
00427
00432 void eventTerminated(MGCPEvent* event);
00433
00438 void changeState(State newState);
00439
00444 void setProvisional(int code = 100);
00445
00450 void send(MGCPMessage* msg);
00451
00452 private:
00453 MGCPTransaction() {}
00454
00455
00456 MGCPEvent* checkResponse(u_int64_t time);
00457
00458 void initTimeout(u_int64_t time, bool extra);
00459
00460 MGCPEvent* terminate();
00461
00462 State m_state;
00463 unsigned int m_id;
00464 bool m_outgoing;
00465 SocketAddr m_address;
00466 MGCPEngine* m_engine;
00467 MGCPMessage* m_cmd;
00468 MGCPMessage* m_provisional;
00469 MGCPMessage* m_response;
00470 MGCPMessage* m_ack;
00471 MGCPEvent* m_lastEvent;
00472 String m_endpoint;
00473 u_int64_t m_nextRetrans;
00474 unsigned int m_crtRetransInterval;
00475 unsigned int m_retransCount;
00476 bool m_timeout;
00477 bool m_ackRequest;
00478 void* m_private;
00479 String m_debug;
00480 };
00481
00486 class YMGCP_API MGCPEndpointId
00487 {
00488 public:
00492 inline MGCPEndpointId()
00493 : m_port(0)
00494 {}
00495
00500 inline MGCPEndpointId(const String& src)
00501 : m_port(0)
00502 { set(src); }
00503
00508 inline MGCPEndpointId(const MGCPEndpointId& value)
00509 : m_port(0)
00510 { set(value.user(),value.host(),value.port()); }
00511
00518 inline MGCPEndpointId(const char* endpoint, const char* host, int port)
00519 : m_port(0)
00520 { set(endpoint,host,port); }
00521
00526 inline const String& id() const
00527 { return m_id; }
00528
00533 inline const String& user() const
00534 { return m_endpoint; }
00535
00540 inline const String& host() const
00541 { return m_host; }
00542
00547 inline int port() const
00548 { return m_port; }
00549
00554 inline void port(int newPort)
00555 { set(m_endpoint,m_host,newPort); }
00556
00563 void set(const char* endpoint, const char* host, int port);
00564
00569 inline void set(const String& src) {
00570 URI uri(src);
00571 set(uri.getUser(),uri.getHost(),uri.getPort());
00572 }
00573
00580 inline bool valid() const {
00581 return m_endpoint && m_endpoint.length() < 256 &&
00582 m_host && m_host.length() < 256;
00583 }
00584
00585 private:
00586 String m_id;
00587 String m_endpoint;
00588 String m_host;
00589 int m_port;
00590 };
00591
00596 class YMGCP_API MGCPEpInfo : public MGCPEndpointId, public GenObject
00597 {
00598 public:
00605 inline MGCPEpInfo(const char* endpoint, const char* host, int port)
00606 : MGCPEndpointId(endpoint,host,port), address(AF_INET) {
00607 address.host(host);
00608 address.port(port);
00609 }
00610
00615 virtual const String& toString() const
00616 { return id(); }
00617
00621 SocketAddr address;
00622
00626 String alias;
00627 };
00628
00635 class YMGCP_API MGCPEndpoint : public RefObject, public MGCPEndpointId, public Mutex
00636 {
00637 public:
00646 MGCPEndpoint(MGCPEngine* engine, const char* user, const char* host, int port);
00647
00651 virtual ~MGCPEndpoint();
00652
00657 virtual const String& toString() const
00658 { return MGCPEndpointId::id(); }
00659
00664 inline MGCPEngine* engine()
00665 { return m_engine; }
00666
00677 MGCPEpInfo* append(const char* endpoint, const char* host, int port = 0);
00678
00682 inline void clear()
00683 { lock(); m_remote.clear(); unlock(); }
00684
00690 MGCPEpInfo* find(const String& epId);
00691
00697 MGCPEpInfo* findAlias(const String& alias);
00698
00703 MGCPEpInfo* peer();
00704
00705 private:
00706 MGCPEngine* m_engine;
00707 ObjList m_remote;
00708 };
00709
00715 class YMGCP_API MGCPEvent
00716 {
00717 friend class MGCPTransaction;
00718 public:
00722 ~MGCPEvent();
00723
00728 inline MGCPTransaction* transaction()
00729 { return m_transaction; }
00730
00735 inline MGCPMessage* message() const
00736 { return m_message; }
00737
00738 protected:
00744 MGCPEvent(MGCPTransaction* trans, MGCPMessage* msg = 0);
00745
00746 private:
00747 MGCPTransaction* m_transaction;
00748 MGCPMessage* m_message;
00749 };
00750
00751 class MGCPPrivateThread;
00752
00762 class YMGCP_API MGCPEngine : public DebugEnabler, public Mutex
00763 {
00764 friend class MGCPPrivateThread;
00765 friend class MGCPTransaction;
00766 public:
00774 MGCPEngine(bool gateway, const char* name = 0, const NamedList* params = 0);
00775
00779 virtual ~MGCPEngine();
00780
00786 inline bool gateway() const
00787 { return m_gateway; }
00788
00793 inline const SocketAddr& address() const
00794 { return m_address; }
00795
00801 inline unsigned int maxRecvPacket() const
00802 { return m_maxRecvPacket; }
00803
00808 inline bool allowUnkCmd() const
00809 { return m_allowUnkCmd; }
00810
00815 inline unsigned int retransInterval() const
00816 { return m_retransInterval; }
00817
00822 inline unsigned int retransCount() const
00823 { return m_retransCount; }
00824
00829 inline u_int64_t extraTime() const
00830 { return m_extraTime; }
00831
00836 inline bool parseParamToLower() const
00837 { return m_parseParamToLower; }
00838
00843 inline bool provisional() const
00844 { return m_provisional; }
00845
00850 inline bool ackRequest() const
00851 { return m_ackRequest; }
00852
00857 inline void ackRequest(bool request)
00858 { m_ackRequest = request; }
00859
00864 virtual void initialize(const NamedList& params);
00865
00871 inline bool knownCommand(const char* cmd)
00872 { Lock lock(this); return (m_knownCommands.find(cmd) != 0); }
00873
00878 void addCommand(const char* cmd);
00879
00884 void attach(MGCPEndpoint* ep);
00885
00893 void detach(MGCPEndpoint* ep, bool del = false, bool delTrans = false);
00894
00900 MGCPEndpoint* findEp(MGCPEndpoint* ep);
00901
00907 MGCPEndpoint* findEp(const String& epId);
00908
00915 MGCPTransaction* findTrans(unsigned int id, bool outgoing);
00916
00921 unsigned int getNextId();
00922
00930 MGCPTransaction* sendCommand(MGCPMessage* cmd, const SocketAddr& address);
00931
00939 bool receive(unsigned char* buffer, SocketAddr& addr);
00940
00949 bool process(u_int64_t time = Time());
00950
00954 void runReceive();
00955
00959 void runProcess();
00960
00966 MGCPEvent* getEvent(u_int64_t time = Time());
00967
00976 virtual bool processEvent(MGCPEvent* event);
00977
00987 virtual bool processEvent(MGCPTransaction* trans, MGCPMessage* msg, void* data);
00988
00995 void returnEvent(MGCPEvent* event);
00996
01006 void cleanup(bool gracefully = true, const char* text = "Shutdown");
01007
01014 static inline int defaultPort(bool gateway)
01015 { return gateway ? 2427 : 2727; }
01016
01020 static TokenDict mgcp_commands[];
01021
01025 static TokenDict mgcp_responses[];
01026
01034 static TokenDict mgcp_reasons[];
01035
01036 protected:
01043 bool sendData(const String& msg, const SocketAddr& address);
01044
01049 void appendTrans(MGCPTransaction* trans);
01050
01056 void removeTrans(MGCPTransaction* trans, bool del);
01057
01061 ObjList m_endpoints;
01062
01066 ObjList m_transactions;
01067
01068 private:
01069
01070 void appendThread(MGCPPrivateThread* thread);
01071
01072 void removeThread(MGCPPrivateThread* thread);
01073
01074
01075 unsigned int* decodeAck(const String& param, unsigned int & count);
01076
01077 bool m_gateway;
01078 bool m_initialized;
01079 unsigned int m_nextId;
01080 Socket m_socket;
01081 SocketAddr m_address;
01082 unsigned int m_maxRecvPacket;
01083 unsigned char* m_recvBuf;
01084 bool m_allowUnkCmd;
01085 unsigned int m_retransInterval;
01086 unsigned int m_retransCount;
01087 u_int64_t m_extraTime;
01088 bool m_parseParamToLower;
01089 bool m_provisional;
01090 bool m_ackRequest;
01091 ObjList m_knownCommands;
01092 ObjList m_threads;
01093 };
01094
01095 }
01096
01097 #endif
01098
01099