Yate
|
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 /* _WINDOWS */ 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("") {} // Avoid using default constructor 00213 // Decode the message line 00214 static MGCPMessage* decodeMessage(const char* line, unsigned int len, unsigned int& trans, 00215 String& error, MGCPEngine* engine); 00216 // Decode message parameters. Return true if found a line containing a dot 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; // Command or string representation of response code 00221 bool m_valid; // False if this message is invalid 00222 int m_code; // Response code or -1 if this is a command 00223 unsigned int m_transaction; // The id of the transaction this message belongs to 00224 String m_endpoint; // The id of the endpoint issuing this message 00225 String m_version; // The protocol version 00226 String m_comment; // The comment attached to a response message 00227 }; 00228 00233 class YMGCP_API MGCPTransaction : public RefObject, public Mutex 00234 { 00235 friend class MGCPEngine; // Process a received message 00236 friend class MGCPEvent; // Access to event termination notification 00237 public: 00241 enum State { 00242 Invalid = 0, // This is an invalid transaction (constructor failed) 00243 Initiated = 1, // An initial command message was sent/received 00244 Trying = 2, // Sent or received a provisional response to the initial message 00245 Responded = 3, // Sent or received a final response to the initial message 00246 Ack = 4, // Response was ack'd 00247 Destroying = 5, // Waiting to be removed from the engine 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() {} // Avoid using default constructor 00454 // Check if received any final response. Create an event. Init timeout. 00455 // Send a response ACK if requested by the response 00456 MGCPEvent* checkResponse(u_int64_t time); 00457 // Init timeout for retransmission or transaction termination 00458 void initTimeout(u_int64_t time, bool extra); 00459 // Remove from engine. Create event. Deref the transaction 00460 MGCPEvent* terminate(); 00461 00462 State m_state; // Current state 00463 unsigned int m_id; // Transaction id 00464 bool m_outgoing; // Transaction direction 00465 SocketAddr m_address; // Remote andpoint's address 00466 MGCPEngine* m_engine; // The engine owning this transaction 00467 MGCPMessage* m_cmd; // The command that created this transaction 00468 MGCPMessage* m_provisional; // The provisional response to the command that created this transaction 00469 MGCPMessage* m_response; // The response to the command that created this transaction 00470 MGCPMessage* m_ack; // The response aknowledgement message sent or received 00471 MGCPEvent* m_lastEvent; // The last generated event 00472 String m_endpoint; // The endpoint owning this transaction 00473 u_int64_t m_nextRetrans; // Retransission or destroy time 00474 unsigned int m_crtRetransInterval; // Current retransmission interval 00475 unsigned int m_retransCount; // Remainig number of retransmissions 00476 bool m_timeout; // Transaction timeout flag 00477 bool m_ackRequest; // Remote is requested to send ACK 00478 void* m_private; // Data used by this transaction's user 00479 String m_debug; // String used to identify the transaction in debug messages 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; // The complete id 00587 String m_endpoint; // The endpoint's name inside the host 00588 String m_host; // Host of this endpoint 00589 int m_port; // Port used by this endpoint 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; // The engine owning this endpoint 00707 ObjList m_remote; // The remote endpoints 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; // The transaction that generated this event 00748 MGCPMessage* m_message; // The message carried by this event, if any 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 // Append a private thread to the list 01070 void appendThread(MGCPPrivateThread* thread); 01071 // Remove private thread from the list without deleting it 01072 void removeThread(MGCPPrivateThread* thread); 01073 // Process ACK received with a message or response 01074 // Return a list of ack'd transactions or 0 if the parameter is incorrect 01075 unsigned int* decodeAck(const String& param, unsigned int & count); 01076 01077 bool m_gateway; // True if this engine is an MGCP gateway, false if call agent 01078 bool m_initialized; // True if the engine was already initialized 01079 unsigned int m_nextId; // Next outgoing transaction id 01080 Socket m_socket; // The socket used to send/receive data 01081 SocketAddr m_address; // The IP address used by this engine 01082 unsigned int m_maxRecvPacket; // The maximum length or received packets 01083 unsigned char* m_recvBuf; // Receiving buffer 01084 bool m_allowUnkCmd; // Allow this engine to send/accept unknown commands 01085 unsigned int m_retransInterval; // Message retransmission interval 01086 unsigned int m_retransCount; // Maximum number of retransmissions for a message 01087 u_int64_t m_extraTime; // Time to live after the transaction terminated gracefully 01088 bool m_parseParamToLower; // Convert received messages' params to lower case 01089 bool m_provisional; // Send provisional responses flag 01090 bool m_ackRequest; // Remote is requested to send ACK 01091 ObjList m_knownCommands; // The list of known commands 01092 ObjList m_threads; 01093 }; 01094 01095 } 01096 01097 #endif /* __YATEMGCP_H */ 01098 01099 /* vi: set ts=8 sw=4 sts=4 noet: */