@1、电话状态变化和电话事件传递
先看一下phapi的电话状态变化图,该图在phapi-old.h中可以找到
/**
* @defgroup phAPI Phone API
* @{
* 格式错误无法正常显示,见PHAPI-OLD.H*/
状态名字都很简单,不在赘述。在PHAPI中,当状态发生变化时都会触发对应的事件。
事件由owplFireCallEvent一系列系列函数发布,函数的声明在qutecom\wifo\phapi\phevents.h中定义。
事件的起源可能是从UI传递的命令,也可能是osip协议栈接收到的标识电话状态改变的数据包。用简单的流程图表示如下:
UI<==>owphone<==>SipWrapper(PhapiWrapper)<==>phapi<==>exosip<==>osip2
@2、拨打电话(makeCall)触发的事件链
按下界面下方拨号按钮拨打电话
$1、从UI传递消息给底层SIP协议栈的过程
QtCallBar::callButtonClickedSlot()//线程上下文在QCoreApplication::instance()中。
==>QtQuteCom::callButtonClicked()
==>CUserProfile::makeCall()
==>UserProfile::makeCall()//在QuteCom::getInstance()实例的上下文中执行
==>PhoneLine-::makeCall()
==>PhoneCall::setState(EnumPhoneCallState::PhoneCallStateDialing)
==>PhApiWrapper::makeCall()
==>owplCallConnect()// phapi
==>phLinePlaceCall_withCa()
| ==>eXosip_build_initial_invite()//exosip
| ==>eXosip_initiate_call()
|==> owplFireCallEvent(CALLSTATE_REMOTE_OFFERING);
owplFireCallEvent将一个CALLSTATE_REMOTE_OFFERING(通话邀请已经发出)的事件通过phapi发给一系列的callBack函数(对象)。
再看CALLSTATE_REMOTE_OFFERING如何传到UI上表示。
owplFireCallEvent(CALLSTATE_REMOTE_OFFERING)//phapi
==>owplFireEvent(EVENT_CATEGORY_CALLSTATE);
==>OWPL_EVENT_CALLBACK_PROC::cbFunc ()//回调函数,见①
==>phApiEventsHandler()//PhapiCallback.cpp
==>PhApiCallbacks::callProgress() //处理电话事件的回调,见②
==>PhApiWrapper::phoneCallStateChangedEvent()
==>PhApiWrapper::phoneCallStateChangedEventHandler()
|==>PhApiWrapper::phoneCallStateChangedEventHandler()//不做任何事,见③
| ==>SipCallbacks::phoneCallStateChangedEventHandler()
==>PhoneLine::setPhoneCallState()
==>PhoneCall::stateChangedEvent()
==>CPhoneCall::stateChangedEventHandler()//注意线程上下文切换至QCoreApplication(界面线程)④
==>QtPhoneCall::stateChangedEvent()//调整界面,显示正在拨号。
①通过PhApiCallbacks::startListeningPhApiEvents()为回调函数队列gEventSubscriber添加消息处理回调,phapi接收到事件后将逐个调用回调函数。因此如果需要监控所有的sip事件而不想修改原有的代码时,可以自己写一个函数xxxxxxxxEventHandler,然后用PhApiCallbacks::startListeningPhApiEvents()把自己写的回调挂上去。
②phApiEventsHandler()函数处理所有的sip事件,除了电话事件外还可以处理注册事件、message事件、notify事件、子状态sub state事件和错误error事件.
③这里PhApiWrapper接收事件,却又不处理,让我感到很疑惑。总之是在SipCallbacks的对象中处理事件。
④CPhoneCall::stateChangedEventHandler()使用PFactory::postEvent(event);,PFactory实际指向QtFactory(在使用GTK UI时指向GTKFactory)。见qutecom\qutecom\src\presentation\main.cpp line 262处。PFactory::postEvent(event)调用QtFactory::postEventImpl(event),最后调用QCoreApplication::postEvent().注意之前的代码执行都是在QuteCom::getInstance()的线程中执行。
但是注意不是所有的上下文切换都在QuteCom::getInstance()和QCoreApplication::getInstance()之间发生,如当收到sip消息时exosip2通信线程将传递事件给QCoreApplication::getInstance()线程处理。