网络挂断一通电话
网络挂断时,L4发送消息PRT_NWRK_CALL_RELEASE,进入回调函数:
void PsCBackNetworkCallDropped(void *info)
{
       if (GetInternalAlert() == TRUE)
    {
        StopInternalOutgoingTone();
    }
 
       ProcessIncomingEvents(CM_PS_NWK_CALL_DROP, info);
} 
g_bUserReject = FALSE;       表示不是用户拒接的,而是missed call
ACTION_RESULT ProcessEndCallIdAndGoBack(void *info)
{
       /* when there's pending req on the dropped call, sync all call state with PS */
    if (GetCallflag(handle, TRUE) & (~CM_HANGUP_REQUESTED) != 0)
    {
        SyncCallList();
    }
 
       switch(被挂断电话的当前状态)
       {
              case CM_INCOMING_STATE:     网络挂断的是来电(对方放弃)
                     SetCallEndCause(0);      gCallEndCause
                     ProcessIncomingEvents(CM_PS_INCOMING_CALL_DROPPED, info);主动拒                                               接任何一种电话的时候,最后也是进入这个状态机中处理。                                              这里没有设置主动拒接的变量标志g_bUserReject
                     break;
              case CM_OUTGOING_STATE:    网络挂断的是OUTGOING CALL,(对方拒接)
                     LogCallInfoForCallHistory(GetOutgoingCallHandle());
            GetEndTimeAndLogUnconnectedMOCall();
                     
                     if启动了自动重拨,
                            则设置一些参数
                            return;
                     
                     设置CM以及CALL的状态。
                     EntryScr1004NotifyEndCallDuration( );
                     break;                   
              case CM_HOLD_CALL:
              case CM_ACTIVE_CALL:
                     SetCallflag(handle, CM_HANGUP_REQUESTED, TRUE);
            OutgoingProcessCMEvent(CM_PS_HANGUPSUC, (void*)&handle);进入函数                                          ProcessPSHangupSucEvent()进行处理。(所有的挂断电话,放                                    弃呼出电话,最后都是进入这个函数进行处理)
       }
}
 
 
 
 
 
 
重要总结:
1.      只有1通ACTIVE CALL时的【暂停】,N通ACTIVE CALL的【保留所有通话】选项都是HiliteM2010ActiveHold(),响应函数是MakeActiveCallHold(),操作都是把ACTIVE CALL HOLD起来。
2.      在1中的ACTIVE CALL变成HOLD CALL之后,如果再恢复通话,即恢复到1通ACTIVE CALL,或者恢复到N通ACTIVE CALL(电话会议),响应函数是:RetrieveHeldCall()。
但是,当发生呼叫等待时,上面2种情况的响应函数都为:HiliteM2014Swap( )。即:
       在只有1通ACTIVE CALL时,发生呼叫等待,此时【暂停】的响应函数
       当有N通ACTIVE CALL时,发生呼叫等待,【保留所有通话】的响应函数
       只有1通HOLD CALL时,呼叫等待,【恢复通话】的响应函数
       有N通HOLD CALL时,呼叫等待,【恢复通话】的响应函数
也就是说,在发生呼叫等待的情况下,电话的ACTIVE与HOLD这两种状态之间的切换,响应函数都是:HiliteM2014Swap()。
另外:所有的【切换】的响应函数也是HiliteM2014Swap()。
我的理解:
MakeActiveCallHold()和RetrieveHeldCall()所发送到L4的消息都是:PRT_RETIEVECALL_EVENT,消息的opnode: CSMCC_HOLD_ACTIVE_AND_ACCEPT。可以看出,这个消息实际上是HOLD当前的ACTIVE CALL,然后接听来电(上面的接听呼叫等待的电话,就是这样的过程)。只不过在没有呼叫等待时,只能是ACTIVE CALL与HOLD CALL之间进行切换,换句话说,如果此时有来电的话,在L4层还是会接听的。正因为这个原因,在有呼叫等待时,如果仅仅是想ACTIVE与HOLD之间转换一下而不接听来电,才只有进行swap,即发送PRT_SWAPCALL_EVENT消息。
详细如下:
1.没有呼叫等待时,电话从ACTIVE——>HOLD
void MakeActiveCallHold(void)
{
       OutgoingProcessCMEvent(CM_KB_HOLDREQ, (void *)NULL);
}
 
ACTION_RESULT ProcessKBHoldReqEvent(void *MsgStruct)
{
       在HOLD之前,必须确保:gChldReqSent=CM_ACTION_NONE
       if (GetChldReqSent() != CM_ACTION_NONE)
    {
        return CM_CALL_FAILURE;
    }
 
       保证所有的电话没有:
       CM_SWAP_REQUESTED,CM_CONF_REQUESTED,CM_ECT_REQUESTED这些标志。
       
       switch (GetCurrentState())    //此时,只可能是ACTIVE STATE
       {
              case CM_ACTIVE_STATE:
            SetHoldFlag();        设置当前所有的ACTIVE CALL的                                                                                  status_flag=CM_HOLD_REQESTED
            MakePsActiveHold((void*)HoldReqSucess);
提醒:在ACTIVE状态下发生呼叫等待,如果接听的话,要先HOLD这个ACTIVE CALL,然后才能接听。那么HOLD这个ACTIVE CALL的时候,也是调用MakePsActiveHold()这个函数,但是传送的CBACK函数不一样。
            break;
       }
}void MakePsActiveHold(void *callBack)
{
       ClearInputEventHandler(MMI_DEVICE_ALL);
       发送到L4的消息是:PRT_RETIEVECALL_EVENT
       消息的opnode是:CSMCC_HOLD_ACTIVE_AND_ACCEPT
}
L4返回消息是:PRT_END_CHLD_RSP,进入CBACK函数:
void HoldReqSucess(void *MsgStruct)
{
       OutgoingProcessCMEvent(CM_PS_HOLDSUC, (void*)MsgStruct);
}
ACTION_RESULT ProcessPSHoldSucEvent(void *MsgStruct)
{
       MakeHold(); 对所有当前状态为ACTIVE的CALL,清除其CM_HOLD_REQUESTED标志,并且设置其当前状态为CM_HOLD_STATE。如果所有的CALL都为HOLD状态,那么就设置CM的当前状态为CM_HOLD_STATE。
 
       EntryScr1005NotiryHoldSucess()
}
 
2.没有发生呼叫等待时,电话从HOLD——>ACTIVE
void RetrieveHeldCall(void)
{
    OutgoingProcessCMEvent(CM_KB_RETRIEVEREQ, (void*)NULL);
}
ACTION_RESULT ProcessKBRetrieveReqEvent(void *MsgStruct)
{
       确定gChldReqSent==CM_ACTION_NONE
       确定所有的CALL都没有:
       CM_SWAP/CONF/ECT_REQUESTED这3个标志
       SetRetrieveFlag();   对所有当前状态为CM_HOLD_STATE的CALL,设置它的                                             status_flag=CM_RETRIEVE_REQUESTED
    MakePsActiveHold((void*)RetrieveReqSucess);与上面的HOLD一个ACTIVE CALL,发                                              送到L4的消息是一样的,仅仅是CBACK函数不一样
}
void MakePsActiveHold(void *callBack)
{
       ClearInputEventHandler(MMI_DEVICE_ALL);
       发送到L4的消息是:PRT_RETRIEVECALL_EVENT
       消息的opnode:CMSCC_HOLD_ACTIVE_AND_ACCEPT
}
L4返回消息:PRT_END_CHLD_RSP,进入:
void RetrieveReqSucess(void *MsgStruct)
{
       OutgoingProcessCMEvent(CM_PS_RETRIEVESUC, (void*)MsgStruct);
}
ACTION_RESULT ProcessPSRetrieveSucEvent(void *MsgStruct)
{
       MakeRetrieve();清除上面设置的:所有HOLD CALL的status_flag标志,并且设置CALL                             的当前状态为ACTIVE STATE。
     EntryScr1006NotifyRetrieveSucess(); 
       设置CM的当前状态为CM_ACTIVE_STATE。注意:如果此时刚好开始发生呼叫等                                   待,那么要设置CM的prev_state=CM_ACTIVE_STATE(当前状态在呼                             叫等待的处理中已经设置了)。
}
 
3.所有状态下的【切换】响应函数+在已经存在呼叫等待时,ACTIVE CALL与HOLD CALL之间的单向切换(【暂停】,【恢复通话】等)
void SwapCall(void)
{
    OutgoingProcessCMEvent(CM_KB_SWAPREQ, (void*)NULL);
}
ACTION_RESULT ProcessKBSwapReqEvent(void *MsgStruct)
{
       确定所有的CALL中都没有CM_SWAP/CONF/ECT_REQUESTED这3个标志
       对当前的所有状态为ACTIVE和HOLD的CALL,设置其
       status_flag=CM_SWAP_REQUESTED
       MakePsSwapCallRequest((void*)SwapReqSucess);
}
void MakePsSwapCallRequest(void *callBack)
{
       ClearInputEventHandler(MMI_DEVICE_ALL);
       发送的消息是:PRT_SWAPCALL_EVENT
       消息的opnode是:CSMCC_SWAP_CALL
}
L4返回消息:PRT_END_CHLD_RSP,进入CBACK函数:
void SwapReqSucess(void *MsgStruct)
{
       OutgoingProcessCMEvent(CM_PS_SWAPSUC, (void*)MsgStruct);
}
ACTION_RESULT ProcessPSSwapSucEvent(void *MsgStruct)
{
       首先与L4同步电话
       if (GetTotalCallCount() > 0)
    {
        SyncCallList();
    }
 
       MakeSwap();检查当前所有CALL的当前状态:如果是ACTIVE,就设置为HOLD;如                                果是HOLD,就设置为ACTIVE。清除他们的status_flag的                                            CM_SWAP_REQUESTED标志。然后,根据当前存在的CALL的不同状                                态来设置CM的当前和之前状态。要注意的是,如果有呼叫等待的电话,                            那么CM的当前状态是为CM_INCOMING_STATE。
    EntryScr1007NotifySwapSucess();
}
 
 
挂断电话:包括挂断所有电话,挂断ACTIVE CALL,挂断HOLD CALL。。。。。。
1.在只有1通ACTIVE CALL,或者只有1通HOLD CALL时,【结束】菜单的响应函数
2.大于1通电话时(不论有几通ACTIVE CALL,几通HOLD CALL),【所有结束】菜单的响应函数
3.大于1通电话时,并且发生呼叫等待,【所有结束】菜单的响应函数
以上3种情况的响应函数都是:KbCBackEndAllCallsExceptIncoming():结束所有的电话
void KbCBackEndAllCallsExceptIncoming(void)
{
    UnSilencethePhone();
    OutgoingProcessCMEvent(CM_KB_HANGUPALLREQ, (void*)NULL);
}
ACTION_RESULT ProcessKBHangupallReqEvent(void *MsgStruct)
{
       SetAllHangupFlag();对所有的CALL,如果当前状态为:HOLD,ACTIVE,OUTGOING,                                         那么就设置其status_flag=CM_HANGUP_REQUESTED.
       SetAllExceptWaitingCallState(CM_DISCONNECTING_STATE); 对所有的CALL,如果当                                      前状态为:HOLD,ACTIVE,OUTGOING,那么就设置其当前状                                                 态为:CM_DISCONNECTING_STATE.
       MakePsHangupallRequest((void*)HangupallReqSucess);
}
void MakePsHangupallRequest(void *callBack)
{
       ClearInputEventHandler(MMI_DEVICE_ALL);
       SetChldReqSent(CM_HANGUPALL_REQ_SENT);设置gChldReqSent
       
       发送到L4的消息是:PRT_ENDALLCALL_EVENT
       消息的opnode:CMSCCD_REL_ALL_EXCEPT_WAITING_CALL
       L4返回的消息是:PRT_ENDALLCALLREQ_SUCCESS.
 
       提醒:挂断一通电话时的消息是:
                     PRT_CALLENDSPECIFIC_EVENT
                     opcode=CSMCC_REL_SPECIFIC_CALL
                     L4返回:PRT_CALLENDSPECIFIC_SUCCESS
 
SetProtocolEventHandler((PsFuncPtr) callBack, PRT_ENDALLCALLREQ_SUCCESS);
    SetProtocolEventHandler((PsFuncPtr) CheckFailureChld, PRT_END_CHLD_RSP);
       这里注册了2个CBACK函数。
}
进入CBACK函数:
void HangupallReqSucess(void *MsgStruct)
{
       gMyhandle = DeriveCallHandle(MsgStruct);
    OutgoingProcessCMEvent(CM_PS_HANGUPALLSUC, (void*)&gMyhandle);
}
ACTION_RESULT ProcessPSHangupallSucEvent(void *MsgStruct)
{
       LogCallInfoForCallHistory(*handle);
       GetEndTimeAndNotifyEndCallDuration(*handle);
       SetCallState((*handle), CM_IDLE_STATE, TRUE);
       设置CM的状态。
}
 
小结:当有N通电话时,如果选择结束所有,那么在CBACK函数HangupallReqSucess()中,只处理第一通电话,也就是call handle=1的电话。其他的电话挂断处理都是通过L4返回消息:PRT_NWRK_CALL_RELEASE,进入PsCBackNetworkCallDropped(void *info),最后进入ProcessPSHangupSucEvent()进行处理的,相当于一通一通的挂断电话。