文章目錄
1. linphone的初始化流程
1. 初始化流程圖:
2. 上下文環境: Sal
Sal 是一個全局類, 是Linphone的上下文環境(Context)。
主要用來保存全局數據、提供基於SIp層消息的回調、回調處理、封裝sip消息併發送sip消息等功能。
1. 保存監聽belle_sip的sip到來的消息的callback數據;
2. 提供處理到來消息的接口;
3. 提供發送sip消息的功能, 包括invite, message等;
Sal class:
class Sal {
public:
//1. 回調事件函數定義
using OnCallReceivedCb = void (*) (SalCallOp *op);
using OnCallRingingCb = void (*) (SalOp *op);
using OnCallAcceptedCb = void (*) (SalOp *op);
using OnCallAckReceivedCb = void (*) (SalOp *op, SalCustomHeader *ack);
using OnCallAckBeingSentCb = void (*) (SalOp *op, SalCustomHeader *ack);
using OnCallUpdatingCb = void (*) (SalOp *op, bool_t isUpdate); // Called when a reINVITE/UPDATE is received
using OnCallTerminatedCb = void (*) (SalOp *op, const char *from);
using OnCallFailureCb = void (*) (SalOp *op);
using OnCallReleasedCb = void (*) (SalOp *op);
using OnCallCancelDoneCb = void (*) (SalOp *op);
using OnAuthRequestedLegacyCb = void (*) (SalOp *op, const char *realm, const char *username);
using OnAuthRequestedCb = bool_t (*) (Sal *sal, SalAuthInfo *info);
using OnAuthFailureCb = void (*) (SalOp *op, SalAuthInfo *info);
using OnRegisterSuccessCb = void (*) (SalOp *op, bool_t registered);
using OnRegisterFailureCb = void (*) (SalOp *op);
using OnVfuRequestCb = void (*) (SalOp *op);
using OnDtmfReceivedCb = void (*) (SalOp *op, char dtmf);
using OnCallReferCb = void (*) (SalOp *op, const SalAddress *referTo);
using OnReferCb = void (*) (SalOp *op, const SalAddress *referTo);
using OnMessageReceivedCb = void (*) (SalOp *op, const SalMessage *msg);
using OnMessageDeliveryUpdateCb = void (*) (SalOp *op, SalMessageDeliveryStatus status);
using OnNotifyReferCb = void (*) (SalOp *op, SalReferStatus status);
using OnSubscribeResponseCb = void (*) (SalOp *op, SalSubscribeStatus status, int willRetry);
using OnNotifyCb = void (*) (SalSubscribeOp *op, SalSubscribeStatus status, const char *event, SalBodyHandler *body);
using OnSubscribeReceivedCb = void (*) (SalSubscribeOp *op, const char *event, const SalBodyHandler *body);
using OnIncomingSubscribeClosedCb = void (*) (SalOp *op);
using OnParsePresenceRequestedCb = void (*) (SalOp *op, const char *contentType, const char *contentSubtype, const char *content, SalPresenceModel **result);
using OnConvertPresenceToXMLRequestedCb = void (*) (SalOp *op, SalPresenceModel *presence, const char *contact, char **content);
using OnNotifyPresenceCb = void (*) (SalOp *op, SalSubscribeStatus ss, SalPresenceModel *model, const char *msg);
using OnSubscribePresenceReceivedCb = void (*) (SalPresenceOp *op, const char *from);
using OnSubscribePresenceClosedCb = void (*) (SalPresenceOp *op, const char *from);
using OnPingReplyCb = void (*) (SalOp *op);
using OnInfoReceivedCb = void (*) (SalOp *op, SalBodyHandler *body);
using OnPublishResponseCb = void (*) (SalOp *op);
using OnNotifyResponseCb = void (*) (SalOp *op);
using OnExpireCb = void (*) (SalOp *op);
//回調數據結構定義;
struct Callbacks {
OnCallReceivedCb call_received;
OnCallReceivedCb call_rejected;
OnCallRingingCb call_ringing;
OnCallAcceptedCb call_accepted;
OnCallAckReceivedCb call_ack_received;
OnCallAckBeingSentCb call_ack_being_sent;
OnCallUpdatingCb call_updating;
OnCallTerminatedCb call_terminated;
OnCallFailureCb call_failure;
OnCallReleasedCb call_released;
OnCallCancelDoneCb call_cancel_done;
OnCallReferCb call_refer_received;
OnAuthFailureCb auth_failure;
OnRegisterSuccessCb register_success;
OnRegisterFailureCb register_failure;
OnVfuRequestCb vfu_request;
OnDtmfReceivedCb dtmf_received;
OnMessageReceivedCb message_received;
OnMessageDeliveryUpdateCb message_delivery_update;
OnNotifyReferCb notify_refer;
OnSubscribeReceivedCb subscribe_received;
OnIncomingSubscribeClosedCb incoming_subscribe_closed;
OnSubscribeResponseCb subscribe_response;
OnNotifyCb notify;
OnSubscribePresenceReceivedCb subscribe_presence_received;
OnSubscribePresenceClosedCb subscribe_presence_closed;
OnParsePresenceRequestedCb parse_presence_requested;
OnConvertPresenceToXMLRequestedCb convert_presence_to_xml_requested;
OnNotifyPresenceCb notify_presence;
OnPingReplyCb ping_reply;
OnAuthRequestedCb auth_requested;
OnInfoReceivedCb info_received;
OnPublishResponseCb on_publish_response;
OnExpireCb on_expire;
OnNotifyResponseCb on_notify_response;
OnReferCb refer_received; // For out of dialog refer
};
Sal(MSFactory *factory);
~Sal();
void setFactory (MSFactory *value) { mFactory = value; }
void setUserPointer (void *value) { mUserPointer = value; }
void *getUserPointer () const { return mUserPointer; }
void setCallbacks (const Callbacks *cbs);
void *getStackImpl() const { return mStack; }
int iterate () { belle_sip_stack_sleep(mStack, 0); return 0; }
void setSendError (int value) { belle_sip_stack_set_send_error(mStack, value); }
void setRecvError (int value) { belle_sip_provider_set_recv_error(mProvider, value); }
// ---------------------------------------------------------------------------
//SIP包裝函數
// SIP parameters
// ---------------------------------------------------------------------------
void setSupportedTags (const std::string &tags);
const std::string &getSupportedTags () const;
void addSupportedTag (const std::string &tag);
void removeSupportedTag (const std::string &tag);
void setUserAgent (const std::string &value);
const std::string &getUserAgent () const;
void appendStackStringToUserAgent ();
bool isContentEncodingAvailable (const std::string &contentEncoding) const;
bool isContentTypeSupported (const std::string &contentType) const;
void addContentTypeSupport (const std::string &contentType);
void removeContentTypeSupport (const std::string &contentType);
void setDefaultSdpHandling (SalOpSDPHandling sdpHandlingMethod);
void setUuid (const std::string &value) { mUuid = value; }
std::string createUuid ();
static std::string generateUuid ();
void enableNatHelper (bool value);
bool natHelperEnabled () const { return mNatHelperEnabled; }
bool pendingTransactionCheckingEnabled () const { return mPendingTransactionChecking; }
void enablePendingTransactionChecking (bool value) { mPendingTransactionChecking = value; }
void setRefresherRetryAfter (int value) { mRefresherRetryAfter = value; }
int getRefresherRetryAfter () const { return mRefresherRetryAfter; }
void enableSipUpdateMethod (bool value) { mEnableSipUpdate = value; }
void useSessionTimers (int expires) { mSessionExpires = expires; }
void useDates (bool value) { mUseDates = value; }
void useOneMatchingCodecPolicy (bool value) { mOneMatchingCodec = value; }
void useRport (bool value);
void enableAutoContacts (bool value) { mAutoContacts = value; }
void enableTestFeatures (bool value) { mEnableTestFeatures = value; }
void useNoInitialRoute (bool value) { mNoInitialRoute = value; }
void enableUnconditionalAnswer (int value) { belle_sip_provider_enable_unconditional_answer(mProvider, value); }
void enableReconnectToPrimaryAsap (bool value) { belle_sip_stack_enable_reconnect_to_primary_asap(mStack, value); }
const std::list<SalOp *> &getPendingAuths () const { return mPendingAuths; }
void setContactLinphoneSpecs (const std::string &value) { mLinphoneSpecs = value; }
// ---------------------------------------------------------------------------
// 網絡參數包裝函數
// Network parameters
// ---------------------------------------------------------------------------
int setListenPort (const std::string &addr, int port, SalTransport tr, bool isTunneled);
int getListeningPort (SalTransport tr);
bool isTransportAvailable (SalTransport tr);
void setTransportTimeout (int value) { belle_sip_stack_set_transport_timeout(mStack, value); }
int getTransportTimeout () const { return belle_sip_stack_get_transport_timeout(mStack); }
void setKeepAlivePeriod (unsigned int value);
unsigned int getKeepAlivePeriod () const { return mKeepAlive; }
void useTcpTlsKeepAlive (bool value) { mUseTcpTlsKeepAlive = value; }
void setDscp (int dscp) { belle_sip_stack_set_default_dscp(mStack, dscp); }
int setTunnel (void *tunnelClient);
void setHttpProxyHost (const std::string &value);
const std::string &getHttpProxyHost () const;
void setHttpProxyPort (int value) { belle_sip_stack_set_http_proxy_port(mStack, value); }
int getHttpProxyPort () const { return belle_sip_stack_get_http_proxy_port(mStack); }
void unlistenPorts ();
void resetTransports ();
// ---------------------------------------------------------------------------
// TLS parameters
// ---------------------------------------------------------------------------
void setSslConfig (void *sslConfig);
void setRootCa (const std::string &value);
void setRootCaData (const std::string &value);
const std::string &getRootCa () const { return mRootCa; }
void verifyServerCertificates (bool value);
void verifyServerCn (bool value);
void setTlsPostcheckCallback(int (*cb)(void *, const bctbx_x509_certificate_t *), void *data);
// ---------------------------------------------------------------------------
// DNS resolution
// ---------------------------------------------------------------------------
void setDnsTimeout (int value) { belle_sip_stack_set_dns_timeout(mStack, value); }
int getDnsTimeout () const { return belle_sip_stack_get_dns_timeout(mStack); }
void setDnsServers (const bctbx_list_t *servers);
void enableDnsSearch (bool value) { belle_sip_stack_enable_dns_search(mStack, (unsigned char)value); }
bool dnsSearchEnabled () const { return !!belle_sip_stack_dns_search_enabled(mStack); }
void enableDnsSrv (bool value) { belle_sip_stack_enable_dns_srv(mStack, (unsigned char)value); }
bool dnsSrvEnabled () const { return !!belle_sip_stack_dns_srv_enabled(mStack); }
void setDnsUserHostsFile (const std::string &value);
const std::string &getDnsUserHostsFile () const;
belle_sip_resolver_context_t *resolveA (const std::string &name, int port, int family, belle_sip_resolver_callback_t cb, void *data);
belle_sip_resolver_context_t *resolve (const std::string &service, const std::string &transport, const std::string &name, int port, int family, belle_sip_resolver_callback_t cb, void *data);
// ---------------------------------------------------------------------------
//計時器函數
// Timers
// ---------------------------------------------------------------------------
belle_sip_source_t *createTimer (belle_sip_source_func_t func, void *data, unsigned int timeoutValueMs, const std::string &timerName);
void cancelTimer (belle_sip_source_t *timer);
private:
struct SalUuid {
unsigned int timeLow;
unsigned short timeMid;
unsigned short timeHiAndVersion;
unsigned char clockSeqHiAndReserved;
unsigned char clockSeqLow;
unsigned char node[6];
};
void setTlsProperties ();
int addListenPort (SalAddress *addr, bool isTunneled);
void makeSupportedHeader ();
void addPendingAuth (SalOp *op);
void removePendingAuth (SalOp *op);
belle_sip_response_t *createResponseFromRequest (belle_sip_request_t *req, int code);
static void unimplementedStub() { lWarning() << "Unimplemented SAL callback"; }
static void removeListeningPoint (belle_sip_listening_point_t *lp,belle_sip_provider_t *prov) {
belle_sip_provider_remove_listening_point(prov, lp);
}
// Internal callbacks
static void processDialogTerminatedCb (void *userCtx, const belle_sip_dialog_terminated_event_t *event);
static void processIoErrorCb (void *userCtx, const belle_sip_io_error_event_t *event);
static void processRequestEventCb (void *userCtx, const belle_sip_request_event_t *event);
static void processResponseEventCb (void *userCtx, const belle_sip_response_event_t *event);
static void processTimeoutCb (void *userCtx, const belle_sip_timeout_event_t *event);
static void processTransactionTerminatedCb (void *userCtx, const belle_sip_transaction_terminated_event_t *event);
static void processAuthRequestedCb (void *userCtx, belle_sip_auth_event_t *event);
//######################Sal中的全局變量 ############################
MSFactory *mFactory = nullptr;
Callbacks mCallbacks = { 0 }; //創建callbacks的實例;
std::list<SalOp *> mPendingAuths;
belle_sip_stack_t *mStack = nullptr;
belle_sip_provider_t *mProvider = nullptr;
belle_sip_header_user_agent_t *mUserAgentHeader = nullptr;
belle_sip_listener_t *mListener = nullptr;
void *mTunnelClient = nullptr;
void *mUserPointer = nullptr; // User pointer
int mSessionExpires = 0;
unsigned int mKeepAlive = 0;
std::string mRootCa;
std::string mRootCaData;
std::string mUuid;
int mRefresherRetryAfter = 60000; // Retry after value for refresher
std::vector<std::string> mSupportedTags;
belle_sip_header_t *mSupportedHeader = nullptr;
bool mOneMatchingCodec = false;
bool mUseTcpTlsKeepAlive = false;
bool mNatHelperEnabled = false;
bool mTlsVerify = true;
bool mTlsVerifyCn = true;
bool mUseDates = false;
bool mAutoContacts = true;
bool mEnableTestFeatures = false;
bool mNoInitialRoute = false;
bool mEnableSipUpdate = true;
SalOpSDPHandling mDefaultSdpHandling = SalOpSDPNormal;
bool mPendingTransactionChecking = true; // For testing purposes
void *mSslConfig = nullptr;
std::vector<std::string> mSupportedContentTypes;
std::string mLinphoneSpecs;
belle_tls_crypto_config_postcheck_callback_t mTlsPostcheckCb;
void *mTlsPostcheckCbData;
// Cache values
mutable std::string mDnsUserHostsFile;
mutable std::string mHttpProxyHost;
mutable std::string mSupported;
mutable std::string mUserAgent;
//##################幾個重要的操作類, 對應不同的業務操作封裝###################
friend class SalOp; //操作類基類
//操作類子類們, 繼承自SalOp {
friend class SalCallOp; //Call操作類
friend class SalRegisterOp; //註冊操作類
friend class SalMessageOp; //短信操作類
friend class SalPresenceOp;
friend class SalSubscribeOp; //訂閱操作類
friend class SalPublishOp; //發佈操作類
friend class SalReferOp;
//}
};
1. Sal的初始化流程
1.Sal構造所初始化全局成員的流程
2. 代碼流程分析
- 構造
Sal::Sal (MSFactory *factory) : mFactory(factory) {
// First create the stack, which initializes the belle-sip object's pool for this thread
//創建stack
mStack = belle_sip_stack_new(nullptr);
//用戶代理的頭結構
mUserAgentHeader = belle_sip_header_user_agent_new();
#if defined(PACKAGE_NAME) && defined(LIBLINPHONE_VERSION)
belle_sip_header_user_agent_add_product(mUserAgentHeader, PACKAGE_NAME "/" LIBLINPHONE_VERSION);
#else
belle_sip_header_user_agent_add_product(mUserAgentHeader, "Unknown");
#endif
appendStackStringToUserAgent();
belle_sip_object_ref(mUserAgentHeader);
//創建Provider
mProvider = belle_sip_stack_create_provider(mStack, nullptr);
enableNatHelper(true);
//創建Sip消息的監聽, 主要用於接收來自Sip協議的消息的回調函數設置.
belle_sip_listener_callbacks_t listenerCallbacks = { 0 };
listenerCallbacks.process_dialog_terminated = processDialogTerminatedCb;
listenerCallbacks.process_io_error = processIoErrorCb;
listenerCallbacks.process_request_event = processRequestEventCb;
listenerCallbacks.process_response_event = processResponseEventCb;
listenerCallbacks.process_timeout = processTimeoutCb;
listenerCallbacks.process_transaction_terminated = processTransactionTerminatedCb;
listenerCallbacks.process_auth_requested = processAuthRequestedCb;
mListener = belle_sip_listener_create_from_callbacks(&listenerCallbacks, this);
//設置監聽的到Provider
belle_sip_provider_add_sip_listener(mProvider, mListener);
}
- 創建stack
//############創建stack
belle_sip_stack_t * belle_sip_stack_new(const char *properties){
//實力實例化Stack結構
belle_sip_stack_t *stack=belle_sip_object_new(belle_sip_stack_t);
bctbx_init_logger(FALSE);
//創建mai_loop結構
stack->ml=belle_sip_main_loop_new ();
//設置一些全局參數, 保存在stack中
stack->timer_config.T1=500;
stack->timer_config.T2=4000;
stack->timer_config.T4=5000;
stack->transport_timeout=63000;
stack->dns_timeout=15000;
stack->dns_srv_enabled=TRUE;
stack->dns_search_enabled=TRUE;
stack->inactive_transport_timeout=3600; /*one hour*/
return stack;
}
//#############創建main_loop結構
belle_sip_main_loop_t *belle_sip_main_loop_new(void){
//實例化main_loop
belle_sip_main_loop_t*m=belle_sip_object_new(belle_sip_main_loop_t);
//main_loop的線程池設置
m->pool=belle_sip_object_pool_push();
m->timer_sources = bctbx_mmap_ullong_new();
bctbx_mutex_init(&m->timer_sources_mutex,NULL);
#ifndef _WIN32
if (pipe(m->control_fds) == -1){
belle_sip_fatal("Cannot create control pipe of main loop thread: %s", strerror(errno));
}
m->thread_id = 0;
#endif
return m;
}
- 創建Provider
belle_sip_provider_t *belle_sip_stack_create_provider(belle_sip_stack_t *s, belle_sip_listening_point_t *lp){
//創建Provider
belle_sip_provider_t *p=belle_sip_provider_new(s,lp);
return p;
}
belle_sip_provider_t *belle_sip_provider_new(belle_sip_stack_t *s, belle_sip_listening_point_t *lp){
//實例化Provider
belle_sip_provider_t *p=belle_sip_object_new(belle_sip_provider_t);
//設置stack到provider的stack成員中
p->stack=s;
p->rport_enabled=1;
p->unconditional_answer = 480;
//添加Listening_point(因爲傳入的lp是NULL, 所以這裏其實不會走進去)
if (lp) belle_sip_provider_add_listening_point(p,lp);
return p;
}
int belle_sip_provider_add_listening_point(belle_sip_provider_t *p, belle_sip_listening_point_t *lp){
if (lp == NULL) {
belle_sip_error("Cannot add NULL lp to provider [%p]",p);
return -1;
}
//強轉Provider爲belle_sip_channel_listener_t, 並添加到lp->channel_listener
belle_sip_listening_point_set_channel_listener(lp,BELLE_SIP_CHANNEL_LISTENER(p));
p->lps=belle_sip_list_append(p->lps,belle_sip_object_ref(lp));
return 0;
}
- 創建belle_sip_listener_callbacks_t, 並設置到Provider
//設置並創建listener
belle_sip_listener_callbacks_t listenerCallbacks = { 0 };
listenerCallbacks.process_dialog_terminated = processDialogTerminatedCb;
listenerCallbacks.process_io_error = processIoErrorCb;
listenerCallbacks.process_request_event = processRequestEventCb;
listenerCallbacks.process_response_event = processResponseEventCb;
listenerCallbacks.process_timeout = processTimeoutCb;
listenerCallbacks.process_transaction_terminated = processTransactionTerminatedCb;
listenerCallbacks.process_auth_requested = processAuthRequestedCb;
mListener = belle_sip_listener_create_from_callbacks(&listenerCallbacks, this);
//設置listener追加到provider的listeners中
belle_sip_provider_add_sip_listener(mProvider, mListener);
//追加mListener到provider的listeners中
void belle_sip_provider_add_sip_listener(belle_sip_provider_t *p, belle_sip_listener_t *l){
p->listeners=belle_sip_list_append(p->listeners,l);
}
3 linphone的端口監聽的初始化
說明:
- 這裏主要是創建監聽socket, 對端口進行監聽操作的流程, 並等待連接到來;
- 當連接到來之後, 會創建child socket, 即服務端的accept函數返回之後創建的通信socket, 真正的和對端進行通信, 屆時會設置對應的通信回調函數;
- 最後將listeningpoint保存在Sal的mProvider中;