由于刚接触MTK不久,很多的呼叫流程搞不清除,例如:CCBS。 搜索了一通,仍然没有找到需要的资料。论坛里请教也不得而解。只好自己看代码瞎琢磨。以下就是自己学习代码之后的记录,错误之处,恳请指正。
1.CCBS(遇忙回叫)。通过学习代码,我的理解过程是:
2.A呼叫B,此时B正忙。
3.A放弃呼叫。
4.B空闲。网络向A发送消息:PRT_CCBS_NOTIFY_IND,进入预先注册的CBACK:
PsCBackCCBSInvoked()
设置gCcbsFlag = TRUE
进入状态机:CM_PS_CCBS_INVOKE
5.状态机处理函数:
ProcessInvokedCcbs()
DeriveCcbsCallInfo(info, &myIncmg);获取CCBS信息:call_handle,number,callType
L4返回的信息结构: typedef struct
{
LOCAL_PARA_HDR
kal_uint8 call_id;
kal_bool number_present;
l4c_number_struct addr;
kal_bool sub_addr_present;
l4c_sub_addr_struct sub_addr;
kal_bool index_present;
kal_uint8 index;
kal_bool bs_code_present;
kal_uint8 bs_code;
kal_bool alert_present;
kal_uint8 alert_pattern;
} mmi_cc_notify_ss_ccbs_ind_struct;
当前的CM状态不能为INCOMING STATE。
设置CM的curr_state=CM_INCOMING_STATE.
AddNewCallInfo( //增加信息之后,电话总数要+1
myIncmg.Number,
GetCurrentState(),
GetPreviousState(),
CM_CALL_MT, //添加为来电
(CM_CALL_HANDLE) myIncmg.callHandle,
CSMCC_VOICE_CALL);
设置gCcbsHandle
EntryScrCCBSInvokeEvent(); //进入显示界面
补充:代码中,在获取电话总数的时候,调用GetTotalCallCount()函数。如果当前发生了CCBS(根据gCcbsFlag来判断),那么返回的电话总数要—1。也就是说电话总数不包括CCBS的这个CALL。
6. EntryScrCCBSInvokeEvent()
获取显示需要的信息
ShowCategory18Screen()
根据当前的电话总数,设置左软件,KEY_SEND,KEY_END键不同的响应函数。
具体为:
(1)当前大于1通电话
左软件:EntryScrCCBSInvokeMultipleOptions() N个通话选项
KEY_SEND:KbCBackCCBSDialCall() 拨号
KEY_END:KbCBackEndAllCallsExceptIncoming() 挂断所有电话(除了MT)
(2)只有CCBS
左软件:KbCBackCCBSDialCall() 拨号
KEY_SEND:KbCBackCCBSDialCall() 拨号
KEY_END:KbCBackCCBSInvokeRejected() 拒接CCBS
到这里,对于CCBS主要有2个选择:拨号和拒接(放弃)。(假定此时只有这个CCBS)
7.左软件或者KEY_SEND键
KbCBackCCBSDialCall()
UnSilencethePhone();
StopIncomingCallIndication();
CCBSUpdateCallInfo(); 注意这个函数:上面发生CCBS,调用AddNewCallInfo()的时候,是作为VOICE,MT CALL添加的。按下左软件或发射键,相当于拨出这个CCBS CALL。因此,在这里,要更新这个CALL的状态为OUTGOINGCALL。主要是设置如下信息:
全局变量:gtmpOutgoingIndex
这个CALL的orgination_flag = CM_CALL_MO
更改状态机:curr_state=CM_OUTGOING_STATE
更改CALL的:curr_state=CM_OUTGOING_STATE
ProcessIncomingEvents(CM_PS_CCBS_INVOKE_DIAL, NULL); 进入状态机
状态机处理函数:
ProcessCCBSDialRequest
SetCCBSFlag(FALSE); //清除CCBS的标志。 下面的操作将与一般的MO相同
SetCCBSHandle(-1);
MakePsActiveHold((void*)CCBSDialResponse);
//发送消息: PRT_RETRIEVECALL_EVENT,HOLD当前的ACTIVE CALLs。CBACK函数CCBSDialResponse()主要就是设置gCcbsFlag = FALSE。
OutgoingProcessCMEvent(CM_PS_SHOW_OUTGOING_CALL_SCREEN, NULL);
//显示OUTGOING SCREEN。与一般的MO相同。
8.KEY_END键。也就是:放弃拨打这个CCBS CALL。
KbCBackCCBSInvokeRejected
UnSilencethePhone();
StopIncomingCallIndication();
ProcessIncomingEvents(CM_PS_CCBS_INVOKE_REJECT, NULL); 进入状态机
状态机处理:
ProcessCCBSRejectRequest()
MakePsSendUDUB((void*)PsCBackCCBSRejectResponse);
//这个函数发送消息:PRT_UDUB_REQ,与拒接呼叫等待发送的消息以及opnode完全相同。(挂断所有的HELD CALL也是发送这个消息,但是opnode不通)
然后L4返回消息:PRT_UDUB_RES_SUCCESS。进入CBACK:
PsCBackCCBSRejectResponse()
ProcessIncomingEvents(CM_PS_CCBS_INCOMING_CALL_REJECTED, info);
状态机处理(从代码形式上看,类似拒接来电):
ProcessCCBSIncomingCallRejected()
根据CM的prev_state,设置CM的状态。
PurgeIncomingCallStructureForCCBS();
在这个函数中,主要执行:
SetCCBSHandle(-1); 设置gCcbsHandle=-1
SetCallState((CM_CALL_HANDLE) count, CM_IDLE_STATE, FALSE);
//在这个函数中,按照missed call处理。由于条件:if(GetCCBSFlag() == FALSE || GetCCBSHandle()!= -1)不成立,因此这个CALL并没有被LOG。最后直接进入显示结束信息的SCREEN:EntryScr1004NotifyEndCallDuration()。
SetCCBSFlag(FALSE); //设置gCcbsFlag=FALSE
GoBackfromNotifyScr();
OVER!!!