Linphone分析 1_初始化

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. 代码流程分析

  1. 构造
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中;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值