diff --git a/core/sip/resolver.cpp b/core/sip/resolver.cpp index 649a1df3..7662b81a 100644 --- a/core/sip/resolver.cpp +++ b/core/sip/resolver.cpp @@ -35,27 +35,17 @@ #include #include -resolver* resolver::_instance=0; - -resolver::resolver() +_resolver::_resolver() { } -resolver::~resolver() +_resolver::~_resolver() { } -resolver* resolver::instance() -{ - if(!_instance) - _instance = new resolver(); - - return _instance; -} - -int resolver::resolve_name(const char* name, sockaddr_storage* sa, +int _resolver::resolve_name(const char* name, sockaddr_storage* sa, const address_type types, const proto_type protos) { struct addrinfo hints,*res=0; diff --git a/core/sip/resolver.h b/core/sip/resolver.h index 09755111..b90ac121 100644 --- a/core/sip/resolver.h +++ b/core/sip/resolver.h @@ -27,6 +27,8 @@ #ifndef _resolver_h_ #define _resolver_h_ +#include "singleton.h" + struct sockaddr_storage; enum address_type { @@ -41,21 +43,19 @@ enum proto_type { UDP=2 }; -class resolver +class _resolver { - static resolver* _instance; - - resolver(); - ~resolver(); - - public: - - static resolver* instance(); - +public: int resolve_name(const char* name, sockaddr_storage* sa, const address_type types, const proto_type protos); + +protected: + _resolver(); + ~_resolver(); + }; +typedef singleton<_resolver> resolver; #endif diff --git a/core/sip/singleton.h b/core/sip/singleton.h new file mode 100644 index 00000000..92fe958a --- /dev/null +++ b/core/sip/singleton.h @@ -0,0 +1,47 @@ +#ifndef _singleton_h_ +#define _singleton_h_ + +#include "../AmThread.h" + +template +class singleton + : public T +{ + singleton() : T() {} + ~singleton() {} + +public: + static singleton* instance() + { + _inst_m.lock(); + if(!_instance) { + _instance = new singleton(); + } + + singleton* ret = _instance; + _inst_m.unlock(); + + return ret; + } + + static void dispose() + { + _inst_m.lock(); + _instance->dispose(); + delete _instance; + _instance = NULL; + _inst_m.unlock(); + } + +private: + static singleton* _instance; + static AmMutex _inst_m; +}; + +template +singleton* singleton::_instance = NULL; + +template +AmMutex singleton::_inst_m; + +#endif diff --git a/core/sip/trans_layer.cpp b/core/sip/trans_layer.cpp index 77c3f69a..f0e9f271 100644 --- a/core/sip/trans_layer.cpp +++ b/core/sip/trans_layer.cpp @@ -55,46 +55,31 @@ #include -/** - * Singleton pointer. - * @see instance() - */ -trans_layer* trans_layer::_instance = NULL; - -bool trans_layer::accept_fr_without_totag = false; - -trans_layer* trans_layer::instance() -{ - if(!_instance) - _instance = new trans_layer(); - - return _instance; -} - +bool _trans_layer::accept_fr_without_totag = false; -trans_layer::trans_layer() +_trans_layer::_trans_layer() : ua(NULL), transport(NULL) { } -trans_layer::~trans_layer() +_trans_layer::~_trans_layer() {} -void trans_layer::register_ua(sip_ua* ua) +void _trans_layer::register_ua(sip_ua* ua) { this->ua = ua; } -void trans_layer::register_transport(trsp_socket* trsp) +void _trans_layer::register_transport(trsp_socket* trsp) { transport = trsp; } -int trans_layer::send_reply(trans_ticket* tt, +int _trans_layer::send_reply(trans_ticket* tt, int reply_code, const cstring& reason, const cstring& to_tag, const cstring& hdrs, const cstring& body) @@ -397,7 +382,7 @@ int trans_layer::send_reply(trans_ticket* tt, return err; } -int trans_layer::send_sl_reply(sip_msg* req, int reply_code, +int _trans_layer::send_sl_reply(sip_msg* req, int reply_code, const cstring& reason, const cstring& hdrs, const cstring& body) { @@ -542,7 +527,7 @@ int trans_layer::send_sl_reply(sip_msg* req, int reply_code, // // Ref. RFC 3261 "12.2.1.1 Generating the Request" // -int trans_layer::set_next_hop(sip_msg* msg) +int _trans_layer::set_next_hop(sip_msg* msg) { assert(msg); @@ -708,7 +693,7 @@ int trans_layer::set_next_hop(sip_msg* msg) return 0; } -void trans_layer::timeout(trans_bucket* bucket, sip_trans* t) +void _trans_layer::timeout(trans_bucket* bucket, sip_trans* t) { t->reset_all_timers(); t->state = TS_TERMINATED; @@ -733,7 +718,7 @@ void trans_layer::timeout(trans_bucket* bucket, sip_trans* t) bucket->remove(t); } -int trans_layer::send_request(sip_msg* msg, trans_ticket* tt) +int _trans_layer::send_request(sip_msg* msg, trans_ticket* tt) { // Request-URI // To @@ -848,7 +833,7 @@ int trans_layer::send_request(sip_msg* msg, trans_ticket* tt) return send_err; } -int trans_layer::cancel(trans_ticket* tt) +int _trans_layer::cancel(trans_ticket* tt) { assert(tt); assert(tt->_bucket && tt->_t); @@ -984,7 +969,7 @@ int trans_layer::cancel(trans_ticket* tt) } -void trans_layer::received_msg(sip_msg* msg) +void _trans_layer::received_msg(sip_msg* msg) { #define DROP_MSG \ delete msg;\ @@ -1161,7 +1146,7 @@ void trans_layer::received_msg(sip_msg* msg) } -int trans_layer::update_uac_reply(trans_bucket* bucket, sip_trans* t, sip_msg* msg) +int _trans_layer::update_uac_reply(trans_bucket* bucket, sip_trans* t, sip_msg* msg) { assert(msg->type == SIP_REPLY); @@ -1321,7 +1306,7 @@ int trans_layer::update_uac_reply(trans_bucket* bucket, sip_trans* t, sip_msg* m return 0; } -int trans_layer::update_uac_request(trans_bucket* bucket, sip_trans*& t, sip_msg* msg) +int _trans_layer::update_uac_request(trans_bucket* bucket, sip_trans*& t, sip_msg* msg) { if(msg->u.request->method != sip_request::ACK){ t = bucket->add_trans(msg,TT_UAC); @@ -1369,7 +1354,7 @@ int trans_layer::update_uac_request(trans_bucket* bucket, sip_trans*& t, sip_msg return 0; } -int trans_layer::update_uas_reply(trans_bucket* bucket, sip_trans* t, int reply_code) +int _trans_layer::update_uas_reply(trans_bucket* bucket, sip_trans* t, int reply_code) { if(t->reply_status >= 200){ ERROR("Transaction has already been closed with a final reply\n"); @@ -1435,7 +1420,7 @@ int trans_layer::update_uas_reply(trans_bucket* bucket, sip_trans* t, int reply_ return t->state; } -int trans_layer::update_uas_request(trans_bucket* bucket, sip_trans* t, sip_msg* msg) +int _trans_layer::update_uas_request(trans_bucket* bucket, sip_trans* t, sip_msg* msg) { if(msg->u.request->method != sip_request::ACK && msg->u.request->method != sip_request::PRACK){ @@ -1475,7 +1460,7 @@ int trans_layer::update_uas_request(trans_bucket* bucket, sip_trans* t, sip_msg* return -1; } -void trans_layer::send_non_200_ack(sip_msg* reply, sip_trans* t) +void _trans_layer::send_non_200_ack(sip_msg* reply, sip_trans* t) { sip_msg* inv = t->msg; @@ -1528,7 +1513,7 @@ void trans_layer::send_non_200_ack(sip_msg* reply, sip_trans* t) } } -void trans_layer::retransmit(sip_trans* t) +void _trans_layer::retransmit(sip_trans* t) { assert(transport); if(!t->retr_buf || !t->retr_len){ @@ -1542,7 +1527,7 @@ void trans_layer::retransmit(sip_trans* t) } } -void trans_layer::retransmit(sip_msg* msg) +void _trans_layer::retransmit(sip_msg* msg) { assert(transport); int send_err = transport->send(&msg->remote_ip,msg->buf,msg->len); @@ -1551,7 +1536,7 @@ void trans_layer::retransmit(sip_msg* msg) } } -void trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr) +void _trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr) { int n = t->type >> 16; int type = t->type & 0xFFFF; diff --git a/core/sip/trans_layer.h b/core/sip/trans_layer.h index a1ae0494..aa70f3d7 100644 --- a/core/sip/trans_layer.h +++ b/core/sip/trans_layer.h @@ -28,6 +28,7 @@ #define _trans_layer_h_ #include "cstring.h" +#include "singleton.h" #include using std::list; @@ -38,49 +39,82 @@ struct sip_trans; struct sip_header; struct sockaddr_storage; +class trans_ticket; class trans_bucket; class trsp_socket; class sip_ua; class timer; -class trans_ticket +/** + * The transaction layer object. + * Uses the singleton pattern. + */ +class _trans_layer { - sip_trans* _t; - trans_bucket* _bucket; - - friend class trans_layer; - friend class AmSipDialog; - friend class SipCtrlInterface; //TODO: make _t, _bucket public?? - public: - trans_ticket() - : _t(0), _bucket(0) {} - trans_ticket(sip_trans* t, trans_bucket* bucket) - : _t(t), _bucket(bucket) {} + /** + * Config option: if true, final replies without + * a to-tag will be accepted for requests which do not + * create a dialog. + */ + static bool accept_fr_without_totag; - trans_ticket(const trans_ticket& ticket) - : _t(ticket._t), _bucket(ticket._bucket) {} -}; + /** + * Register a SIP UA. + * This method MUST be called ONCE. + */ + void register_ua(sip_ua* ua); -class trans_layer -{ - /** - * Singleton pointer. - * @see instance() + /** + * Register a transport instance. + * This method MUST be called ONCE. */ - static trans_layer* _instance; + void register_transport(trsp_socket* trsp); - sip_ua* ua; - trsp_socket* transport; - + /** + * Sends a UAS reply. + * If a body is included, the hdrs parameter should + * include a well-formed 'Content-Type', but no + * 'Content-Length' header. + */ + int send_reply(trans_ticket* tt, + int reply_code, const cstring& reason, + const cstring& to_tag, const cstring& hdrs, + const cstring& body); + + /** + * Sends a UAC request. + * Caution: Route headers should not be added to the + * general header list (msg->hdrs). + * @param [in] msg Pre-built message. + * @param [out] tt transaction ticket (needed for replies & CANCEL) + */ + int send_request(sip_msg* msg, trans_ticket* tt); + + /** + * Cancels a request. + * A CANCEL request is sent if necessary. + * @param tt transaction ticket from the original INVITE. + */ + int cancel(trans_ticket* tt); - /** Avoid external instantiation. @see instance(). */ - trans_layer(); + /** + * Called by the transport layer + * when a new message has been recived. + */ + void received_msg(sip_msg* msg); - /** Avoid external instantiation. @see instance(). */ - ~trans_layer(); + /** + * This is called by the transaction timer callback. + * At this place, the bucket is already locked, so + * please be quick. + */ + void timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr); + sip_ua* ua; + trsp_socket* transport; + /** * Implements the state changes for the UAC state machine * @return -1 if errors @@ -131,75 +165,34 @@ class trans_layer */ void timeout(trans_bucket* bucket, sip_trans* t); - public: - - /** - * Config option: if true, final replies without - * a to-tag will be accepted for requests which do not - * create a dialog. - */ - static bool accept_fr_without_totag; - - /** - * Retrieve the singleton instance. - */ - static trans_layer* instance(); - - /** - * Register a SIP UA. - * This method MUST be called ONCE. - */ - void register_ua(sip_ua* ua); - - /** - * Register a transport instance. - * This method MUST be called ONCE. - */ - void register_transport(trsp_socket* trsp); +protected: + /** Avoid external instantiation. @see singleton. */ + _trans_layer(); + ~_trans_layer(); + +}; - /** - * Sends a UAS reply. - * If a body is included, the hdrs parameter should - * include a well-formed 'Content-Type', but no - * 'Content-Length' header. - */ - int send_reply(trans_ticket* tt, - int reply_code, const cstring& reason, - const cstring& to_tag, const cstring& hdrs, - const cstring& body); +typedef singleton<_trans_layer> trans_layer; - /** - * Sends a UAC request. - * Caution: Route headers should not be added to the - * general header list (msg->hdrs). - * @param [in] msg Pre-built message. - * @param [out] tt transaction ticket (needed for replies & CANCEL) - */ - int send_request(sip_msg* msg, trans_ticket* tt); - - /** - * Cancels a request. - * A CANCEL request is sent if necessary. - * @param tt transaction ticket from the original INVITE. - */ - int cancel(trans_ticket* tt); +class trans_ticket +{ + sip_trans* _t; + trans_bucket* _bucket; + friend class _trans_layer; + friend class AmSipDialog; + friend class SipCtrlInterface; //TODO: make _t, _bucket public?? - /** - * Called by the transport layer - * when a new message has been recived. - */ - void received_msg(sip_msg* msg); - - /** - * This is called by the transaction timer callback. - * At this place, the bucket is already locked, so - * please be quick. - */ - void timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr); -}; +public: + trans_ticket() + : _t(0), _bucket(0) {} + trans_ticket(sip_trans* t, trans_bucket* bucket) + : _t(t), _bucket(bucket) {} + trans_ticket(const trans_ticket& ticket) + : _t(ticket._t), _bucket(ticket._bucket) {} +}; #endif // _trans_layer_h_ diff --git a/core/sip/wheeltimer.cpp b/core/sip/wheeltimer.cpp index 1d289f4b..8446b008 100644 --- a/core/sip/wheeltimer.cpp +++ b/core/sip/wheeltimer.cpp @@ -42,26 +42,26 @@ timer::~timer() -wheeltimer* wheeltimer::_instance=NULL; +//wheeltimer* wheeltimer::_instance=NULL; -wheeltimer* wheeltimer::instance() -{ - if(!_instance) - _instance = new wheeltimer(); +// wheeltimer* wheeltimer::instance() +// { +// if(!_instance) +// _instance = new wheeltimer(); - return _instance; -} +// return _instance; +// } -wheeltimer::wheeltimer() +_wheeltimer::_wheeltimer() : wall_clock(0) { } -wheeltimer::~wheeltimer() +_wheeltimer::~_wheeltimer() { } -void wheeltimer::insert_timer(timer* t) +void _wheeltimer::insert_timer(timer* t) { //add new timer to user request list utimer_add_m.lock(); @@ -69,7 +69,7 @@ void wheeltimer::insert_timer(timer* t) utimer_add_m.unlock(); } -void wheeltimer::remove_timer(timer* t) +void _wheeltimer::remove_timer(timer* t) { //add new timer to user request list utimer_rem_m.lock(); @@ -77,7 +77,7 @@ void wheeltimer::remove_timer(timer* t) utimer_rem_m.unlock(); } -void wheeltimer::run() +void _wheeltimer::run() { struct timeval now,next_tick,diff,tick; @@ -113,7 +113,7 @@ void wheeltimer::run() -void wheeltimer::update_wheel(int wheel) +void _wheeltimer::update_wheel(int wheel) { // do not try do update wheel 0 if(!wheel) @@ -136,7 +136,7 @@ void wheeltimer::update_wheel(int wheel) } } -void wheeltimer::turn_wheel() +void _wheeltimer::turn_wheel() { u_int32_t mask = ((1< (unsigned int)(1<<31)); } -void wheeltimer::place_timer(timer* t) +void _wheeltimer::place_timer(timer* t) { if(less_ts(t->expires,wall_clock)){ @@ -220,7 +220,7 @@ void wheeltimer::place_timer(timer* t) place_timer(t,WHEELS-1); } -void wheeltimer::place_timer(timer* t, int wheel) +void _wheeltimer::place_timer(timer* t, int wheel) { unsigned int pos; unsigned int clock_mask = t->expires ^ wall_clock; @@ -239,7 +239,7 @@ void wheeltimer::place_timer(timer* t, int wheel) add_timer_to_wheel(t,wheel,pos); } -void wheeltimer::add_timer_to_wheel(timer* t, int wheel, unsigned int pos) +void _wheeltimer::add_timer_to_wheel(timer* t, int wheel, unsigned int pos) { t->next = wheels[wheel][pos].next; wheels[wheel][pos].next = t; @@ -251,7 +251,7 @@ void wheeltimer::add_timer_to_wheel(timer* t, int wheel, unsigned int pos) t->prev = &(wheels[wheel][pos]); } -void wheeltimer::delete_timer(timer* t) +void _wheeltimer::delete_timer(timer* t) { if(t->prev) t->prev->next = t->next; diff --git a/core/sip/wheeltimer.h b/core/sip/wheeltimer.h index 99eb44a1..1f79d365 100644 --- a/core/sip/wheeltimer.h +++ b/core/sip/wheeltimer.h @@ -81,11 +81,11 @@ public: }; +#include "singleton.h" -class wheeltimer: public AmThread +class _wheeltimer: + public AmThread { - static wheeltimer* _instance; - //the timer wheel base_timer wheels[WHEELS][ELMTS_PER_WHEEL]; @@ -104,9 +104,6 @@ class wheeltimer: public AmThread //list with expired timers base_timer utimer_expired; - wheeltimer(); - ~wheeltimer(); - void turn_wheel(); void update_wheel(int wheel); @@ -122,10 +119,10 @@ protected: void run(); void on_stop(){} -public: - - static wheeltimer* instance(); + _wheeltimer(); + ~_wheeltimer(); +public: //clock reference volatile u_int32_t wall_clock; // 32 bits @@ -134,6 +131,7 @@ public: void remove_timer(timer* t); }; +typedef singleton<_wheeltimer> wheeltimer; #endif